mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			7628 lines
		
	
	
		
			239 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			7628 lines
		
	
	
		
			239 KiB
		
	
	
	
		
			Java
		
	
	
	
/* Collections.java -- Utility class with methods to operate on collections
 | 
						|
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
 | 
						|
   Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package java.util;
 | 
						|
 | 
						|
import gnu.java.lang.CPStringBuilder;
 | 
						|
 | 
						|
import java.io.Serializable;
 | 
						|
 | 
						|
/**
 | 
						|
 * Utility class consisting of static methods that operate on, or return
 | 
						|
 * Collections. Contains methods to sort, search, reverse, fill and shuffle
 | 
						|
 * Collections, methods to facilitate interoperability with legacy APIs that
 | 
						|
 * are unaware of collections, a method to return a list which consists of
 | 
						|
 * multiple copies of one element, and methods which "wrap" collections to give
 | 
						|
 * them extra properties, such as thread-safety and unmodifiability.
 | 
						|
 * <p>
 | 
						|
 *
 | 
						|
 * All methods which take a collection throw a {@link NullPointerException} if
 | 
						|
 * that collection is null. Algorithms which can change a collection may, but
 | 
						|
 * are not required, to throw the {@link UnsupportedOperationException} that
 | 
						|
 * the underlying collection would throw during an attempt at modification.
 | 
						|
 * For example,
 | 
						|
 * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code>
 | 
						|
 * does not throw a exception, even though addAll is an unsupported operation
 | 
						|
 * on a singleton; the reason for this is that addAll did not attempt to
 | 
						|
 * modify the set.
 | 
						|
 *
 | 
						|
 * @author Original author unknown
 | 
						|
 * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
 * @author Tom Tromey (tromey@redhat.com)
 | 
						|
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
 * @see Collection
 | 
						|
 * @see Set
 | 
						|
 * @see List
 | 
						|
 * @see Map
 | 
						|
 * @see Arrays
 | 
						|
 * @since 1.2
 | 
						|
 * @status updated to 1.5
 | 
						|
 */
 | 
						|
public class Collections
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * Constant used to decide cutoff for when a non-RandomAccess list should
 | 
						|
   * be treated as sequential-access. Basically, quadratic behavior is
 | 
						|
   * acceptable for small lists when the overhead is so small in the first
 | 
						|
   * place. I arbitrarily set it to 16, so it may need some tuning.
 | 
						|
   */
 | 
						|
  private static final int LARGE_LIST_SIZE = 16;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Determines if a list should be treated as a sequential-access one.
 | 
						|
   * Rather than the old method of JDK 1.3 of assuming only instanceof
 | 
						|
   * AbstractSequentialList should be sequential, this uses the new method
 | 
						|
   * of JDK 1.4 of assuming anything that does NOT implement RandomAccess
 | 
						|
   * and exceeds a large (unspecified) size should be sequential.
 | 
						|
   *
 | 
						|
   * @param l the list to check
 | 
						|
   * @return <code>true</code> if it should be treated as sequential-access
 | 
						|
   */
 | 
						|
  private static boolean isSequential(List<?> l)
 | 
						|
  {
 | 
						|
    return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class is non-instantiable.
 | 
						|
   */
 | 
						|
  private Collections()
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * An immutable, serializable, empty Set.
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static final Set EMPTY_SET = new EmptySet();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an immutable, serializable parameterized empty set.
 | 
						|
   * Unlike the constant <code>EMPTY_SET</code>, the set returned by
 | 
						|
   * this method is type-safe.
 | 
						|
   *
 | 
						|
   * @return an empty parameterized set.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  @SuppressWarnings("unchecked")
 | 
						|
  public static final <T> Set<T> emptySet()
 | 
						|
  {
 | 
						|
    return (Set<T>) EMPTY_SET;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #EMPTY_SET}. This class name is required
 | 
						|
   * for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class EmptySet<T> extends AbstractSet<T>
 | 
						|
    implements Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1582296315990362920L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * A private constructor adds overhead.
 | 
						|
     */
 | 
						|
    EmptySet()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size: always 0!
 | 
						|
     * @return 0.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns an iterator that does not iterate.
 | 
						|
     * @return A non-iterating iterator.
 | 
						|
     */
 | 
						|
    // This is really cheating! I think it's perfectly valid, though.
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
    public Iterator<T> iterator()
 | 
						|
    {
 | 
						|
      return (Iterator<T>) EMPTY_LIST.iterator();
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractSet.
 | 
						|
    /**
 | 
						|
     * The empty set never contains anything.
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This is true only if the given collection is also empty.
 | 
						|
     * @param c The collection of objects which are to be compared
 | 
						|
     *          against the members of this set.
 | 
						|
     * @return <code>true</code> if c is empty.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return c.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Equal only if the other set is empty.
 | 
						|
     * @param o The object to compare with this set.
 | 
						|
     * @return <code>true</code> if o is an empty instance of <code>Set</code>.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return o instanceof Set<?> && ((Set<?>) o).isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The hashcode is always 0.
 | 
						|
     * @return 0.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with a <code>false</code> result.
 | 
						|
     * @param o The object to remove.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with a <code>false</code> result.
 | 
						|
     * @param c The collection of objects which should
 | 
						|
     *          all be removed from this set.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean removeAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with a <code>false</code> result.
 | 
						|
     * @param c The collection of objects which should
 | 
						|
     *          all be retained within this set.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean retainAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The array is always empty.
 | 
						|
     * @return A new array with a size of 0.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return new Object[0];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * We don't even need to use reflection!
 | 
						|
     * @param a An existing array, which can be empty.
 | 
						|
     * @return The original array with any existing
 | 
						|
     *         initial element set to null.
 | 
						|
     */
 | 
						|
    public <E> E[] toArray(E[] a)
 | 
						|
    {
 | 
						|
      if (a.length > 0)
 | 
						|
        a[0] = null;
 | 
						|
      return a;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The string never changes.
 | 
						|
     *
 | 
						|
     * @return the string "[]".
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "[]";
 | 
						|
    }
 | 
						|
  } // class EmptySet
 | 
						|
 | 
						|
  /**
 | 
						|
   * An immutable, serializable, empty List, which implements RandomAccess.
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   */
 | 
						|
  public static final List EMPTY_LIST = new EmptyList();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an immutable, serializable parameterized empty list.
 | 
						|
   * Unlike the constant <code>EMPTY_LIST</code>, the list returned by
 | 
						|
   * this method is type-safe.
 | 
						|
   *
 | 
						|
   * @return an empty parameterized list.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  @SuppressWarnings("unchecked")
 | 
						|
  public static final <T> List<T> emptyList()
 | 
						|
  {
 | 
						|
    return (List<T>) EMPTY_LIST;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #EMPTY_LIST}. This class name is required
 | 
						|
   * for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class EmptyList<T> extends AbstractList<T>
 | 
						|
    implements Serializable, RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 8842843931221139166L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * A private constructor adds overhead.
 | 
						|
     */
 | 
						|
    EmptyList()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size is always 0.
 | 
						|
     * @return 0.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * No matter the index, it is out of bounds.  This
 | 
						|
     * method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param index The index of the element to retrieve.
 | 
						|
     * @return the object at the specified index.
 | 
						|
     * @throws IndexOutOfBoundsException as any given index
 | 
						|
     *         is outside the bounds of an empty array.
 | 
						|
     */
 | 
						|
    public T get(int index)
 | 
						|
    {
 | 
						|
      throw new IndexOutOfBoundsException();
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractList.
 | 
						|
    /**
 | 
						|
     * Never contains anything.
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This is true only if the given collection is also empty.
 | 
						|
     * @param c The collection of objects, which should be compared
 | 
						|
     *          against the members of this list.
 | 
						|
     * @return <code>true</code> if c is also empty.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return c.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Equal only if the other list is empty.
 | 
						|
     * @param o The object to compare against this list.
 | 
						|
     * @return <code>true</code> if o is also an empty instance of
 | 
						|
     *         <code>List</code>.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return o instanceof List<?> && ((List<?>) o).isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The hashcode is always 1.
 | 
						|
     * @return 1.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns -1.
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return -1.
 | 
						|
     */
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns -1.
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return -1.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with <code>false</code> result.
 | 
						|
     * @param o The object to remove.
 | 
						|
     * @return -1.
 | 
						|
     */
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with <code>false</code> result.
 | 
						|
     * @param c The collection of objects which should
 | 
						|
     *          all be removed from this list.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean removeAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Always succeeds with <code>false</code> result.
 | 
						|
     * @param c The collection of objects which should
 | 
						|
     *          all be retained within this list.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean retainAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The array is always empty.
 | 
						|
     * @return A new array with a size of 0.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return new Object[0];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * We don't even need to use reflection!
 | 
						|
     * @param a An existing array, which can be empty.
 | 
						|
     * @return The original array with any existing
 | 
						|
     *         initial element set to null.
 | 
						|
     */
 | 
						|
    public <E> E[] toArray(E[] a)
 | 
						|
    {
 | 
						|
      if (a.length > 0)
 | 
						|
        a[0] = null;
 | 
						|
      return a;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The string never changes.
 | 
						|
     *
 | 
						|
     * @return the string "[]".
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "[]";
 | 
						|
    }
 | 
						|
  } // class EmptyList
 | 
						|
 | 
						|
  /**
 | 
						|
   * An immutable, serializable, empty Map.
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static final Map EMPTY_MAP = new EmptyMap();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an immutable, serializable parameterized empty map.
 | 
						|
   * Unlike the constant <code>EMPTY_MAP</code>, the map returned by
 | 
						|
   * this method is type-safe.
 | 
						|
   *
 | 
						|
   * @return an empty parameterized map.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  @SuppressWarnings("unchecked")
 | 
						|
  public static final <K,V> Map<K,V> emptyMap()
 | 
						|
  {
 | 
						|
    return (Map<K,V>) EMPTY_MAP;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #EMPTY_MAP}. This class name is required
 | 
						|
   * for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class EmptyMap<K, V> extends AbstractMap<K, V>
 | 
						|
    implements Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 6428348081105594320L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * A private constructor adds overhead.
 | 
						|
     */
 | 
						|
    EmptyMap()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * There are no entries.
 | 
						|
     * @return The empty set.
 | 
						|
     */
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
    public Set<Map.Entry<K, V>> entrySet()
 | 
						|
    {
 | 
						|
      return (Set<Map.Entry<K, V>>) EMPTY_SET;
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractMap.
 | 
						|
    /**
 | 
						|
     * No entries!
 | 
						|
     * @param key The key to search for.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean containsKey(Object key)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * No entries!
 | 
						|
     * @param value The value to search for.
 | 
						|
     * @return <code>false</code>.
 | 
						|
     */
 | 
						|
    public boolean containsValue(Object value)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Equal to all empty maps.
 | 
						|
     * @param o The object o to compare against this map.
 | 
						|
     * @return <code>true</code> if o is also an empty instance of
 | 
						|
     *         <code>Map</code>.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return o instanceof Map<?,?> && ((Map<?,?>) o).isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * No mappings, so this returns null.
 | 
						|
     * @param o The key of the object to retrieve.
 | 
						|
     * @return null.
 | 
						|
     */
 | 
						|
    public V get(Object o)
 | 
						|
    {
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The hashcode is always 0.
 | 
						|
     * @return 0.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * No entries.
 | 
						|
     * @return The empty set.
 | 
						|
     */
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
    public Set<K> keySet()
 | 
						|
    {
 | 
						|
      return (Set<K>) EMPTY_SET;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Remove always succeeds, with null result.
 | 
						|
     * @param o The key of the mapping to remove.
 | 
						|
     * @return null, as there is never a mapping for o.
 | 
						|
     */
 | 
						|
    public V remove(Object o)
 | 
						|
    {
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Size is always 0.
 | 
						|
     * @return 0.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * No entries. Technically, EMPTY_SET, while more specific than a general
 | 
						|
     * Collection, will work. Besides, that's what the JDK uses!
 | 
						|
     * @return The empty set.
 | 
						|
     */
 | 
						|
    @SuppressWarnings("unchecked")
 | 
						|
    public Collection<V> values()
 | 
						|
    {
 | 
						|
      return (Collection<V>) EMPTY_SET;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The string never changes.
 | 
						|
     *
 | 
						|
     * @return the string "[]".
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "[]";
 | 
						|
    }
 | 
						|
  } // class EmptyMap
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Compare two objects with or without a Comparator. If c is null, uses the
 | 
						|
   * natural ordering. Slightly slower than doing it inline if the JVM isn't
 | 
						|
   * clever, but worth it for removing a duplicate of the search code.
 | 
						|
   * Note: This code is also used in Arrays (for sort as well as search).
 | 
						|
   */
 | 
						|
  static final <T> int compare(T o1, T o2, Comparator<? super T> c)
 | 
						|
  {
 | 
						|
    return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Perform a binary search of a List for a key, using the natural ordering of
 | 
						|
   * the elements. The list must be sorted (as by the sort() method) - if it is
 | 
						|
   * not, the behavior of this method is undefined, and may be an infinite
 | 
						|
   * loop. Further, the key must be comparable with every item in the list. If
 | 
						|
   * the list contains the key more than once, any one of them may be found.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
 | 
						|
   * and uses a linear search with O(n) link traversals and log(n) comparisons
 | 
						|
   * with {@link AbstractSequentialList} lists. Note: although the
 | 
						|
   * specification allows for an infinite loop if the list is unsorted, it will
 | 
						|
   * not happen in this (Classpath) implementation.
 | 
						|
   *
 | 
						|
   * @param l the list to search (must be sorted)
 | 
						|
   * @param key the value to search for
 | 
						|
   * @return the index at which the key was found, or -n-1 if it was not
 | 
						|
   *         found, where n is the index of the first value higher than key or
 | 
						|
   *         a.length if there is no such value
 | 
						|
   * @throws ClassCastException if key could not be compared with one of the
 | 
						|
   *         elements of l
 | 
						|
   * @throws NullPointerException if a null element has compareTo called
 | 
						|
   * @see #sort(List)
 | 
						|
   */
 | 
						|
  public static <T> int binarySearch(List<? extends Comparable<? super T>> l,
 | 
						|
                                     T key)
 | 
						|
  {
 | 
						|
    return binarySearch(l, key, null);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Perform a binary search of a List for a key, using a supplied Comparator.
 | 
						|
   * The list must be sorted (as by the sort() method with the same Comparator)
 | 
						|
   * - if it is not, the behavior of this method is undefined, and may be an
 | 
						|
   * infinite loop. Further, the key must be comparable with every item in the
 | 
						|
   * list. If the list contains the key more than once, any one of them may be
 | 
						|
   * found. If the comparator is null, the elements' natural ordering is used.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
 | 
						|
   * and uses a linear search with O(n) link traversals and log(n) comparisons
 | 
						|
   * with {@link AbstractSequentialList} lists. Note: although the
 | 
						|
   * specification allows for an infinite loop if the list is unsorted, it will
 | 
						|
   * not happen in this (Classpath) implementation.
 | 
						|
   *
 | 
						|
   * @param l the list to search (must be sorted)
 | 
						|
   * @param key the value to search for
 | 
						|
   * @param c the comparator by which the list is sorted
 | 
						|
   * @return the index at which the key was found, or -n-1 if it was not
 | 
						|
   *         found, where n is the index of the first value higher than key or
 | 
						|
   *         a.length if there is no such value
 | 
						|
   * @throws ClassCastException if key could not be compared with one of the
 | 
						|
   *         elements of l
 | 
						|
   * @throws NullPointerException if a null element is compared with natural
 | 
						|
   *         ordering (only possible when c is null)
 | 
						|
   * @see #sort(List, Comparator)
 | 
						|
   */
 | 
						|
  public static <T> int binarySearch(List<? extends T> l, T key,
 | 
						|
                                     Comparator<? super T> c)
 | 
						|
  {
 | 
						|
    int pos = 0;
 | 
						|
    int low = 0;
 | 
						|
    int hi = l.size() - 1;
 | 
						|
 | 
						|
    // We use a linear search with log(n) comparisons using an iterator
 | 
						|
    // if the list is sequential-access.
 | 
						|
    if (isSequential(l))
 | 
						|
      {
 | 
						|
        ListIterator<T> itr = ((List<T>) l).listIterator();
 | 
						|
        int i = 0;
 | 
						|
        T o = itr.next(); // Assumes list is not empty (see isSequential)
 | 
						|
        boolean forward = true;
 | 
						|
        while (low <= hi)
 | 
						|
          {
 | 
						|
            pos = (low + hi) >>> 1;
 | 
						|
            if (i < pos)
 | 
						|
              {
 | 
						|
                if (!forward)
 | 
						|
                  itr.next(); // Changing direction first.
 | 
						|
                for ( ; i != pos; i++, o = itr.next())
 | 
						|
                  ;
 | 
						|
                forward = true;
 | 
						|
              }
 | 
						|
            else
 | 
						|
              {
 | 
						|
                if (forward)
 | 
						|
                  itr.previous(); // Changing direction first.
 | 
						|
                for ( ; i != pos; i--, o = itr.previous())
 | 
						|
                  ;
 | 
						|
                forward = false;
 | 
						|
              }
 | 
						|
            final int d = compare(o, key, c);
 | 
						|
            if (d == 0)
 | 
						|
              return pos;
 | 
						|
            else if (d > 0)
 | 
						|
              hi = pos - 1;
 | 
						|
            else
 | 
						|
              // This gets the insertion point right on the last loop
 | 
						|
              low = ++pos;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        while (low <= hi)
 | 
						|
          {
 | 
						|
            pos = (low + hi) >>> 1;
 | 
						|
            final int d = compare(((List<T>) l).get(pos), key, c);
 | 
						|
            if (d == 0)
 | 
						|
              return pos;
 | 
						|
            else if (d > 0)
 | 
						|
              hi = pos - 1;
 | 
						|
            else
 | 
						|
              // This gets the insertion point right on the last loop
 | 
						|
              low = ++pos;
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    // If we failed to find it, we do the same whichever search we did.
 | 
						|
    return -pos - 1;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Copy one list to another. If the destination list is longer than the
 | 
						|
   * source list, the remaining elements are unaffected. This method runs in
 | 
						|
   * linear time.
 | 
						|
   *
 | 
						|
   * @param dest the destination list
 | 
						|
   * @param source the source list
 | 
						|
   * @throws IndexOutOfBoundsException if the destination list is shorter
 | 
						|
   *         than the source list (the destination will be unmodified)
 | 
						|
   * @throws UnsupportedOperationException if dest.listIterator() does not
 | 
						|
   *         support the set operation
 | 
						|
   */
 | 
						|
  public static <T> void copy(List<? super T> dest, List<? extends T> source)
 | 
						|
  {
 | 
						|
    int pos = source.size();
 | 
						|
    if (dest.size() < pos)
 | 
						|
      throw new IndexOutOfBoundsException("Source does not fit in dest");
 | 
						|
 | 
						|
    Iterator<? extends T> i1 = source.iterator();
 | 
						|
    ListIterator<? super T> i2 = dest.listIterator();
 | 
						|
 | 
						|
    while (--pos >= 0)
 | 
						|
      {
 | 
						|
        i2.next();
 | 
						|
        i2.set(i1.next());
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an Enumeration over a collection. This allows interoperability
 | 
						|
   * with legacy APIs that require an Enumeration as input.
 | 
						|
   *
 | 
						|
   * @param c the Collection to iterate over
 | 
						|
   * @return an Enumeration backed by an Iterator over c
 | 
						|
   */
 | 
						|
  public static <T> Enumeration<T> enumeration(Collection<T> c)
 | 
						|
  {
 | 
						|
    final Iterator<T> i = c.iterator();
 | 
						|
    return new Enumeration<T>()
 | 
						|
    {
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if there are more elements to
 | 
						|
       * be enumerated.
 | 
						|
       *
 | 
						|
       * @return The result of <code>hasNext()</code>
 | 
						|
       *         called on the underlying iterator.
 | 
						|
       */
 | 
						|
      public final boolean hasMoreElements()
 | 
						|
      {
 | 
						|
        return i.hasNext();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the next element to be enumerated.
 | 
						|
       *
 | 
						|
       * @return The result of <code>next()</code>
 | 
						|
       *         called on the underlying iterator.
 | 
						|
       */
 | 
						|
      public final T nextElement()
 | 
						|
      {
 | 
						|
        return i.next();
 | 
						|
      }
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Replace every element of a list with a given value. This method runs in
 | 
						|
   * linear time.
 | 
						|
   *
 | 
						|
   * @param l the list to fill.
 | 
						|
   * @param val the object to vill the list with.
 | 
						|
   * @throws UnsupportedOperationException if l.listIterator() does not
 | 
						|
   *         support the set operation.
 | 
						|
   */
 | 
						|
  public static <T> void fill(List<? super T> l, T val)
 | 
						|
  {
 | 
						|
    ListIterator<? super T> itr = l.listIterator();
 | 
						|
    for (int i = l.size() - 1; i >= 0; --i)
 | 
						|
      {
 | 
						|
        itr.next();
 | 
						|
        itr.set(val);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the starting index where the specified sublist first occurs
 | 
						|
   * in a larger list, or -1 if there is no matching position. If
 | 
						|
   * <code>target.size() > source.size()</code>, this returns -1,
 | 
						|
   * otherwise this implementation uses brute force, checking for
 | 
						|
   * <code>source.sublist(i, i + target.size()).equals(target)</code>
 | 
						|
   * for all possible i.
 | 
						|
   *
 | 
						|
   * @param source the list to search
 | 
						|
   * @param target the sublist to search for
 | 
						|
   * @return the index where found, or -1
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static int indexOfSubList(List<?> source, List<?> target)
 | 
						|
  {
 | 
						|
    int ssize = source.size();
 | 
						|
    for (int i = 0, j = target.size(); j <= ssize; i++, j++)
 | 
						|
      if (source.subList(i, j).equals(target))
 | 
						|
        return i;
 | 
						|
    return -1;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the starting index where the specified sublist last occurs
 | 
						|
   * in a larger list, or -1 if there is no matching position. If
 | 
						|
   * <code>target.size() > source.size()</code>, this returns -1,
 | 
						|
   * otherwise this implementation uses brute force, checking for
 | 
						|
   * <code>source.sublist(i, i + target.size()).equals(target)</code>
 | 
						|
   * for all possible i.
 | 
						|
   *
 | 
						|
   * @param source the list to search
 | 
						|
   * @param target the sublist to search for
 | 
						|
   * @return the index where found, or -1
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static int lastIndexOfSubList(List<?> source, List<?> target)
 | 
						|
  {
 | 
						|
    int ssize = source.size();
 | 
						|
    for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
 | 
						|
      if (source.subList(i, j).equals(target))
 | 
						|
        return i;
 | 
						|
    return -1;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an ArrayList holding the elements visited by a given
 | 
						|
   * Enumeration. This method exists for interoperability between legacy
 | 
						|
   * APIs and the new Collection API.
 | 
						|
   *
 | 
						|
   * @param e the enumeration to put in a list
 | 
						|
   * @return a list containing the enumeration elements
 | 
						|
   * @see ArrayList
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static <T> ArrayList<T> list(Enumeration<T> e)
 | 
						|
  {
 | 
						|
    ArrayList<T> l = new ArrayList<T>();
 | 
						|
    while (e.hasMoreElements())
 | 
						|
      l.add(e.nextElement());
 | 
						|
    return l;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find the maximum element in a Collection, according to the natural
 | 
						|
   * ordering of the elements. This implementation iterates over the
 | 
						|
   * Collection, so it works in linear time.
 | 
						|
   *
 | 
						|
   * @param c the Collection to find the maximum element of
 | 
						|
   * @return the maximum element of c
 | 
						|
   * @exception NoSuchElementException if c is empty
 | 
						|
   * @exception ClassCastException if elements in c are not mutually comparable
 | 
						|
   * @exception NullPointerException if null.compareTo is called
 | 
						|
   */
 | 
						|
  public static <T extends Object & Comparable<? super T>>
 | 
						|
  T max(Collection<? extends T> c)
 | 
						|
  {
 | 
						|
    return max(c, null);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find the maximum element in a Collection, according to a specified
 | 
						|
   * Comparator. This implementation iterates over the Collection, so it
 | 
						|
   * works in linear time.
 | 
						|
   *
 | 
						|
   * @param c the Collection to find the maximum element of
 | 
						|
   * @param order the Comparator to order the elements by, or null for natural
 | 
						|
   *        ordering
 | 
						|
   * @return the maximum element of c
 | 
						|
   * @throws NoSuchElementException if c is empty
 | 
						|
   * @throws ClassCastException if elements in c are not mutually comparable
 | 
						|
   * @throws NullPointerException if null is compared by natural ordering
 | 
						|
   *        (only possible when order is null)
 | 
						|
   */
 | 
						|
  public static <T> T max(Collection<? extends T> c,
 | 
						|
                          Comparator<? super T> order)
 | 
						|
  {
 | 
						|
    Iterator<? extends T> itr = c.iterator();
 | 
						|
    T max = itr.next(); // throws NoSuchElementException
 | 
						|
    int csize = c.size();
 | 
						|
    for (int i = 1; i < csize; i++)
 | 
						|
      {
 | 
						|
        T o = itr.next();
 | 
						|
        if (compare(max, o, order) < 0)
 | 
						|
          max = o;
 | 
						|
      }
 | 
						|
    return max;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find the minimum element in a Collection, according to the natural
 | 
						|
   * ordering of the elements. This implementation iterates over the
 | 
						|
   * Collection, so it works in linear time.
 | 
						|
   *
 | 
						|
   * @param c the Collection to find the minimum element of
 | 
						|
   * @return the minimum element of c
 | 
						|
   * @throws NoSuchElementException if c is empty
 | 
						|
   * @throws ClassCastException if elements in c are not mutually comparable
 | 
						|
   * @throws NullPointerException if null.compareTo is called
 | 
						|
   */
 | 
						|
  public static <T extends Object & Comparable<? super T>>
 | 
						|
  T min(Collection<? extends T> c)
 | 
						|
  {
 | 
						|
    return min(c, null);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find the minimum element in a Collection, according to a specified
 | 
						|
   * Comparator. This implementation iterates over the Collection, so it
 | 
						|
   * works in linear time.
 | 
						|
   *
 | 
						|
   * @param c the Collection to find the minimum element of
 | 
						|
   * @param order the Comparator to order the elements by, or null for natural
 | 
						|
   *        ordering
 | 
						|
   * @return the minimum element of c
 | 
						|
   * @throws NoSuchElementException if c is empty
 | 
						|
   * @throws ClassCastException if elements in c are not mutually comparable
 | 
						|
   * @throws NullPointerException if null is compared by natural ordering
 | 
						|
   *        (only possible when order is null)
 | 
						|
   */
 | 
						|
  public static <T> T min(Collection<? extends T> c,
 | 
						|
                          Comparator<? super T> order)
 | 
						|
  {
 | 
						|
    Iterator<? extends T> itr = c.iterator();
 | 
						|
    T min = itr.next(); // throws NoSuchElementExcception
 | 
						|
    int csize = c.size();
 | 
						|
    for (int i = 1; i < csize; i++)
 | 
						|
      {
 | 
						|
        T o = itr.next();
 | 
						|
        if (compare(min, o, order) > 0)
 | 
						|
          min = o;
 | 
						|
      }
 | 
						|
    return min;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates an immutable list consisting of the same object repeated n times.
 | 
						|
   * The returned object is tiny, consisting of only a single reference to the
 | 
						|
   * object and a count of the number of elements. It is Serializable, and
 | 
						|
   * implements RandomAccess. You can use it in tandem with List.addAll for
 | 
						|
   * fast list construction.
 | 
						|
   *
 | 
						|
   * @param n the number of times to repeat the object
 | 
						|
   * @param o the object to repeat
 | 
						|
   * @return a List consisting of n copies of o
 | 
						|
   * @throws IllegalArgumentException if n < 0
 | 
						|
   * @see List#addAll(Collection)
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   */
 | 
						|
  public static <T> List<T> nCopies(final int n, final T o)
 | 
						|
  {
 | 
						|
    return new CopiesList<T>(n, o);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #nCopies(int, Object)}. This class name
 | 
						|
   * is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class CopiesList<T> extends AbstractList<T>
 | 
						|
    implements Serializable, RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 2739099268398711800L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The count of elements in this list.
 | 
						|
     * @serial the list size
 | 
						|
     */
 | 
						|
    private final int n;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The repeated list element.
 | 
						|
     * @serial the list contents
 | 
						|
     */
 | 
						|
    private final T element;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructs the list.
 | 
						|
     *
 | 
						|
     * @param n the count
 | 
						|
     * @param o the object
 | 
						|
     * @throws IllegalArgumentException if n < 0
 | 
						|
     */
 | 
						|
    CopiesList(int n, T o)
 | 
						|
    {
 | 
						|
      if (n < 0)
 | 
						|
        throw new IllegalArgumentException();
 | 
						|
      this.n = n;
 | 
						|
      element = o;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size is fixed.
 | 
						|
     * @return The size of the list.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return n;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The same element is returned.
 | 
						|
     * @param index The index of the element to be returned (irrelevant
 | 
						|
     *        as the list contains only copies of <code>element</code>).
 | 
						|
     * @return The element used by this list.
 | 
						|
     */
 | 
						|
    public T get(int index)
 | 
						|
    {
 | 
						|
      if (index < 0 || index >= n)
 | 
						|
        throw new IndexOutOfBoundsException();
 | 
						|
      return element;
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractList.
 | 
						|
    /**
 | 
						|
     * This list only contains one element.
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return <code>true</code> if o is the element used by this list.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return n > 0 && equals(o, element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The index is either 0 or -1.
 | 
						|
     * @param o The object to find the index of.
 | 
						|
     * @return 0 if <code>o == element</code>, -1 if not.
 | 
						|
     */
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      return (n > 0 && equals(o, element)) ? 0 : -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The index is either n-1 or -1.
 | 
						|
     * @param o The object to find the last index of.
 | 
						|
     * @return The last index in the list if <code>o == element</code>,
 | 
						|
     *         -1 if not.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      return equals(o, element) ? n - 1 : -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * A subList is just another CopiesList.
 | 
						|
     * @param from The starting bound of the sublist.
 | 
						|
     * @param to The ending bound of the sublist.
 | 
						|
     * @return A list of copies containing <code>from - to</code>
 | 
						|
     *         elements, all of which are equal to the element
 | 
						|
     *         used by this list.
 | 
						|
     */
 | 
						|
    public List<T> subList(int from, int to)
 | 
						|
    {
 | 
						|
      if (from < 0 || to > n)
 | 
						|
        throw new IndexOutOfBoundsException();
 | 
						|
      return new CopiesList<T>(to - from, element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The array is easy.
 | 
						|
     * @return An array of size n filled with copies of
 | 
						|
     *         the element used by this list.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      Object[] a = new Object[n];
 | 
						|
      Arrays.fill(a, element);
 | 
						|
      return a;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The string is easy to generate.
 | 
						|
     * @return A string representation of the list.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      CPStringBuilder r = new CPStringBuilder("{");
 | 
						|
      for (int i = n - 1; --i > 0; )
 | 
						|
        r.append(element).append(", ");
 | 
						|
      r.append(element).append("}");
 | 
						|
      return r.toString();
 | 
						|
    }
 | 
						|
  } // class CopiesList
 | 
						|
 | 
						|
  /**
 | 
						|
   * Replace all instances of one object with another in the specified list.
 | 
						|
   * The list does not change size. An element e is replaced if
 | 
						|
   * <code>oldval == null ? e == null : oldval.equals(e)</code>.
 | 
						|
   *
 | 
						|
   * @param list the list to iterate over
 | 
						|
   * @param oldval the element to replace
 | 
						|
   * @param newval the new value for the element
 | 
						|
   * @return <code>true</code> if a replacement occurred.
 | 
						|
   * @throws UnsupportedOperationException if the list iterator does not allow
 | 
						|
   *         for the set operation
 | 
						|
   * @throws ClassCastException if newval is of a type which cannot be added
 | 
						|
   *         to the list
 | 
						|
   * @throws IllegalArgumentException if some other aspect of newval stops
 | 
						|
   *         it being added to the list
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static <T> boolean replaceAll(List<T> list, T oldval, T newval)
 | 
						|
  {
 | 
						|
    ListIterator<T> itr = list.listIterator();
 | 
						|
    boolean replace_occured = false;
 | 
						|
    for (int i = list.size(); --i >= 0; )
 | 
						|
      if (AbstractCollection.equals(oldval, itr.next()))
 | 
						|
        {
 | 
						|
          itr.set(newval);
 | 
						|
          replace_occured = true;
 | 
						|
        }
 | 
						|
    return replace_occured;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Reverse a given list. This method works in linear time.
 | 
						|
   *
 | 
						|
   * @param l the list to reverse
 | 
						|
   * @throws UnsupportedOperationException if l.listIterator() does not
 | 
						|
   *         support the set operation
 | 
						|
   */
 | 
						|
  public static void reverse(List<?> l)
 | 
						|
  {
 | 
						|
    ListIterator i1 = l.listIterator();
 | 
						|
    int pos1 = 1;
 | 
						|
    int pos2 = l.size();
 | 
						|
    ListIterator i2 = l.listIterator(pos2);
 | 
						|
    while (pos1 < pos2)
 | 
						|
      {
 | 
						|
        Object o1 = i1.next();
 | 
						|
    Object o2 = i2.previous();
 | 
						|
        i1.set(o2);
 | 
						|
        i2.set(o1);
 | 
						|
        ++pos1;
 | 
						|
        --pos2;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get a comparator that implements the reverse of the ordering
 | 
						|
   * specified by the given Comparator. If the Comparator is null,
 | 
						|
   * this is equivalent to {@link #reverseOrder()}.  The return value
 | 
						|
   * of this method is Serializable, if the specified Comparator is
 | 
						|
   * either Serializable or null.
 | 
						|
   *
 | 
						|
   * @param c the comparator to invert
 | 
						|
   * @return a comparator that imposes reverse ordering
 | 
						|
   * @see Comparable
 | 
						|
   * @see Serializable
 | 
						|
   *
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  public static <T> Comparator<T> reverseOrder(final Comparator<T> c)
 | 
						|
  {
 | 
						|
    if (c == null)
 | 
						|
      return (Comparator<T>) rcInstance;
 | 
						|
    return new ReverseComparator<T> ()
 | 
						|
    {
 | 
						|
      public int compare(T a, T b)
 | 
						|
      {
 | 
						|
        return - c.compare(a, b);
 | 
						|
      }
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get a comparator that implements the reverse of natural ordering. In
 | 
						|
   * other words, this sorts Comparable objects opposite of how their
 | 
						|
   * compareTo method would sort. This makes it easy to sort into reverse
 | 
						|
   * order, by simply passing Collections.reverseOrder() to the sort method.
 | 
						|
   * The return value of this method is Serializable.
 | 
						|
   *
 | 
						|
   * @return a comparator that imposes reverse natural ordering
 | 
						|
   * @see Comparable
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Comparator<T> reverseOrder()
 | 
						|
  {
 | 
						|
    return (Comparator<T>) rcInstance;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object for {@link #reverseOrder()}.
 | 
						|
   */
 | 
						|
  private static final ReverseComparator rcInstance = new ReverseComparator();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #reverseOrder()}. This class name
 | 
						|
   * is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class ReverseComparator<T>
 | 
						|
    implements Comparator<T>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 7207038068494060240L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * A private constructor adds overhead.
 | 
						|
     */
 | 
						|
    ReverseComparator()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Compare two objects in reverse natural order.
 | 
						|
     *
 | 
						|
     * @param a the first object
 | 
						|
     * @param b the second object
 | 
						|
     * @return <, ==, or > 0 according to b.compareTo(a)
 | 
						|
     */
 | 
						|
    public int compare(T a, T b)
 | 
						|
    {
 | 
						|
      return ((Comparable) b).compareTo(a);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Rotate the elements in a list by a specified distance. After calling this
 | 
						|
   * method, the element now at index <code>i</code> was formerly at index
 | 
						|
   * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
 | 
						|
   * either <code>Collections.rotate(l, 4)</code> or
 | 
						|
   * <code>Collections.rotate(l, -1)</code>, the new contents are
 | 
						|
   * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
 | 
						|
   * just a portion of the list. For example, to move element <code>a</code>
 | 
						|
   * forward two positions in the original example, use
 | 
						|
   * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
 | 
						|
   * result in <code>[t, n, k, a, s]</code>.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * If the list is small or implements {@link RandomAccess}, the
 | 
						|
   * implementation exchanges the first element to its destination, then the
 | 
						|
   * displaced element, and so on until a circuit has been completed. The
 | 
						|
   * process is repeated if needed on the second element, and so forth, until
 | 
						|
   * all elements have been swapped.  For large non-random lists, the
 | 
						|
   * implementation breaks the list into two sublists at index
 | 
						|
   * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
 | 
						|
   * pieces, then reverses the overall list.
 | 
						|
   *
 | 
						|
   * @param list the list to rotate
 | 
						|
   * @param distance the distance to rotate by; unrestricted in value
 | 
						|
   * @throws UnsupportedOperationException if the list does not support set
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static void rotate(List<?> list, int distance)
 | 
						|
  {
 | 
						|
    int size = list.size();
 | 
						|
    if (size == 0)
 | 
						|
      return;
 | 
						|
    distance %= size;
 | 
						|
    if (distance == 0)
 | 
						|
      return;
 | 
						|
    if (distance < 0)
 | 
						|
      distance += size;
 | 
						|
 | 
						|
    if (isSequential(list))
 | 
						|
      {
 | 
						|
        reverse(list);
 | 
						|
        reverse(list.subList(0, distance));
 | 
						|
        reverse(list.subList(distance, size));
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        // Determine the least common multiple of distance and size, as there
 | 
						|
        // are (distance / LCM) loops to cycle through.
 | 
						|
        int a = size;
 | 
						|
        int lcm = distance;
 | 
						|
        int b = a % lcm;
 | 
						|
        while (b != 0)
 | 
						|
          {
 | 
						|
            a = lcm;
 | 
						|
            lcm = b;
 | 
						|
            b = a % lcm;
 | 
						|
          }
 | 
						|
 | 
						|
        // Now, make the swaps. We must take the remainder every time through
 | 
						|
        // the inner loop so that we don't overflow i to negative values.
 | 
						|
        List<Object> objList = (List<Object>) list;
 | 
						|
        while (--lcm >= 0)
 | 
						|
          {
 | 
						|
            Object o = objList.get(lcm);
 | 
						|
            for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
 | 
						|
              o = objList.set(i, o);
 | 
						|
            objList.set(lcm, o);
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Shuffle a list according to a default source of randomness. The algorithm
 | 
						|
   * used iterates backwards over the list, swapping each element with an
 | 
						|
   * element randomly selected from the elements in positions less than or
 | 
						|
   * equal to it (using r.nextInt(int)).
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This algorithm would result in a perfectly fair shuffle (that is, each
 | 
						|
   * element would have an equal chance of ending up in any position) if r were
 | 
						|
   * a perfect source of randomness. In practice the results are merely very
 | 
						|
   * close to perfect.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This method operates in linear time. To do this on large lists which do
 | 
						|
   * not implement {@link RandomAccess}, a temporary array is used to acheive
 | 
						|
   * this speed, since it would be quadratic access otherwise.
 | 
						|
   *
 | 
						|
   * @param l the list to shuffle
 | 
						|
   * @throws UnsupportedOperationException if l.listIterator() does not
 | 
						|
   *         support the set operation
 | 
						|
   */
 | 
						|
  public static void shuffle(List<?> l)
 | 
						|
  {
 | 
						|
    if (defaultRandom == null)
 | 
						|
      {
 | 
						|
        synchronized (Collections.class)
 | 
						|
          {
 | 
						|
            if (defaultRandom == null)
 | 
						|
              defaultRandom = new Random();
 | 
						|
          }
 | 
						|
      }
 | 
						|
    shuffle(l, defaultRandom);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Cache a single Random object for use by shuffle(List). This improves
 | 
						|
   * performance as well as ensuring that sequential calls to shuffle() will
 | 
						|
   * not result in the same shuffle order occurring: the resolution of
 | 
						|
   * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
 | 
						|
   */
 | 
						|
  private static Random defaultRandom = null;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Shuffle a list according to a given source of randomness. The algorithm
 | 
						|
   * used iterates backwards over the list, swapping each element with an
 | 
						|
   * element randomly selected from the elements in positions less than or
 | 
						|
   * equal to it (using r.nextInt(int)).
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This algorithm would result in a perfectly fair shuffle (that is, each
 | 
						|
   * element would have an equal chance of ending up in any position) if r were
 | 
						|
   * a perfect source of randomness. In practise (eg if r = new Random()) the
 | 
						|
   * results are merely very close to perfect.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * This method operates in linear time. To do this on large lists which do
 | 
						|
   * not implement {@link RandomAccess}, a temporary array is used to acheive
 | 
						|
   * this speed, since it would be quadratic access otherwise.
 | 
						|
   *
 | 
						|
   * @param l the list to shuffle
 | 
						|
   * @param r the source of randomness to use for the shuffle
 | 
						|
   * @throws UnsupportedOperationException if l.listIterator() does not
 | 
						|
   *         support the set operation
 | 
						|
   */
 | 
						|
  public static void shuffle(List<?> l, Random r)
 | 
						|
  {
 | 
						|
    int lsize = l.size();
 | 
						|
    List<Object> list = (List<Object>) l;
 | 
						|
    ListIterator<Object> i = list.listIterator(lsize);
 | 
						|
    boolean sequential = isSequential(l);
 | 
						|
    Object[] a = null; // stores a copy of the list for the sequential case
 | 
						|
 | 
						|
    if (sequential)
 | 
						|
      a = list.toArray();
 | 
						|
 | 
						|
    for (int pos = lsize - 1; pos > 0; --pos)
 | 
						|
      {
 | 
						|
        // Obtain a random position to swap with. pos + 1 is used so that the
 | 
						|
        // range of the random number includes the current position.
 | 
						|
        int swap = r.nextInt(pos + 1);
 | 
						|
 | 
						|
        // Swap the desired element.
 | 
						|
        Object o;
 | 
						|
        if (sequential)
 | 
						|
          {
 | 
						|
            o = a[swap];
 | 
						|
            a[swap] = i.previous();
 | 
						|
          }
 | 
						|
        else
 | 
						|
          o = list.set(swap, i.previous());
 | 
						|
 | 
						|
        i.set(o);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the frequency of the specified object within the supplied
 | 
						|
   * collection.  The frequency represents the number of occurrences of
 | 
						|
   * elements within the collection which return <code>true</code> when
 | 
						|
   * compared with the object using the <code>equals</code> method.
 | 
						|
   *
 | 
						|
   * @param c the collection to scan for occurrences of the object.
 | 
						|
   * @param o the object to locate occurrances of within the collection.
 | 
						|
   * @throws NullPointerException if the collection is <code>null</code>.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  public static int frequency (Collection<?> c, Object o)
 | 
						|
  {
 | 
						|
    int result = 0;
 | 
						|
    final Iterator<?> it = c.iterator();
 | 
						|
    while (it.hasNext())
 | 
						|
      {
 | 
						|
        Object v = it.next();
 | 
						|
        if (AbstractCollection.equals(o, v))
 | 
						|
          ++result;
 | 
						|
      }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds all the specified elements to the given collection, in a similar
 | 
						|
   * way to the <code>addAll</code> method of the <code>Collection</code>.
 | 
						|
   * However, this is a variable argument method which allows the new elements
 | 
						|
   * to be specified individually or in array form, as opposed to the list
 | 
						|
   * required by the collection's <code>addAll</code> method.  This has
 | 
						|
   * benefits in both simplicity (multiple elements can be added without
 | 
						|
   * having to be wrapped inside a grouping structure) and efficiency
 | 
						|
   * (as a redundant list doesn't have to be created to add an individual
 | 
						|
   * set of elements or an array).
 | 
						|
   *
 | 
						|
   * @param c the collection to which the elements should be added.
 | 
						|
   * @param a the elements to be added to the collection.
 | 
						|
   * @return true if the collection changed its contents as a result.
 | 
						|
   * @throws UnsupportedOperationException if the collection does not support
 | 
						|
   *                                       addition.
 | 
						|
   * @throws NullPointerException if one or more elements in a are null,
 | 
						|
   *                              and the collection does not allow null
 | 
						|
   *                              elements.  This exception is also thrown
 | 
						|
   *                              if either <code>c</code> or <code>a</code>
 | 
						|
   *                              are null.
 | 
						|
   * @throws IllegalArgumentException if the collection won't allow an element
 | 
						|
   *                                  to be added for some other reason.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  public static <T> boolean addAll(Collection<? super T> c, T... a)
 | 
						|
  {
 | 
						|
    boolean overall = false;
 | 
						|
 | 
						|
    for (T element : a)
 | 
						|
      {
 | 
						|
        boolean result = c.add(element);
 | 
						|
        if (result)
 | 
						|
          overall = true;
 | 
						|
      }
 | 
						|
    return overall;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns true if the two specified collections have no elements in
 | 
						|
   * common.  This method may give unusual results if one or both collections
 | 
						|
   * use a non-standard equality test.  In the trivial case of comparing
 | 
						|
   * a collection with itself, this method returns true if, and only if,
 | 
						|
   * the collection is empty.
 | 
						|
   *
 | 
						|
   * @param c1 the first collection to compare.
 | 
						|
   * @param c2 the second collection to compare.
 | 
						|
   * @return true if the collections are disjoint.
 | 
						|
   * @throws NullPointerException if either collection is null.
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  public static boolean disjoint(Collection<?> c1, Collection<?> c2)
 | 
						|
  {
 | 
						|
    Collection<Object> oc1 = (Collection<Object>) c1;
 | 
						|
    final Iterator<Object> it = oc1.iterator();
 | 
						|
    while (it.hasNext())
 | 
						|
      if (c2.contains(it.next()))
 | 
						|
        return false;
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtain an immutable Set consisting of a single element. The return value
 | 
						|
   * of this method is Serializable.
 | 
						|
   *
 | 
						|
   * @param o the single element
 | 
						|
   * @return an immutable Set containing only o
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Set<T> singleton(T o)
 | 
						|
  {
 | 
						|
    return new SingletonSet<T>(o);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #singleton(Object)}. This class name
 | 
						|
   * is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SingletonSet<T> extends AbstractSet<T>
 | 
						|
    implements Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 3193687207550431679L;
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * The single element; package visible for use in nested class.
 | 
						|
     * @serial the singleton
 | 
						|
     */
 | 
						|
    final T element;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Construct a singleton.
 | 
						|
     * @param o the element
 | 
						|
     */
 | 
						|
    SingletonSet(T o)
 | 
						|
    {
 | 
						|
      element = o;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size: always 1!
 | 
						|
     * @return 1.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns an iterator over the lone element.
 | 
						|
     */
 | 
						|
    public Iterator<T> iterator()
 | 
						|
    {
 | 
						|
      return new Iterator<T>()
 | 
						|
      {
 | 
						|
        /**
 | 
						|
         * Flag to indicate whether or not the element has
 | 
						|
         * been retrieved.
 | 
						|
         */
 | 
						|
        private boolean hasNext = true;
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns <code>true</code> if elements still remain to be
 | 
						|
         * iterated through.
 | 
						|
         *
 | 
						|
         * @return <code>true</code> if the element has not yet been returned.
 | 
						|
         */
 | 
						|
        public boolean hasNext()
 | 
						|
        {
 | 
						|
          return hasNext;
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns the element.
 | 
						|
         *
 | 
						|
         * @return The element used by this singleton.
 | 
						|
         * @throws NoSuchElementException if the object
 | 
						|
         *         has already been retrieved.
 | 
						|
         */
 | 
						|
        public T next()
 | 
						|
        {
 | 
						|
          if (hasNext)
 | 
						|
          {
 | 
						|
            hasNext = false;
 | 
						|
            return element;
 | 
						|
          }
 | 
						|
          else
 | 
						|
            throw new NoSuchElementException();
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Removes the element from the singleton.
 | 
						|
         * As this set is immutable, this will always
 | 
						|
         * throw an exception.
 | 
						|
         *
 | 
						|
         * @throws UnsupportedOperationException as the
 | 
						|
         *         singleton set doesn't support
 | 
						|
         *         <code>remove()</code>.
 | 
						|
         */
 | 
						|
        public void remove()
 | 
						|
        {
 | 
						|
          throw new UnsupportedOperationException();
 | 
						|
        }
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractSet.
 | 
						|
    /**
 | 
						|
     * The set only contains one element.
 | 
						|
     *
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return <code>true</code> if o == the element of the singleton.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return equals(o, element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This is true if the other collection only contains the element.
 | 
						|
     *
 | 
						|
     * @param c A collection to compare against this singleton.
 | 
						|
     * @return <code>true</code> if c only contains either no elements or
 | 
						|
     *         elements equal to the element in this singleton.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      Iterator<?> i = c.iterator();
 | 
						|
      int pos = c.size();
 | 
						|
      while (--pos >= 0)
 | 
						|
        if (! equals(i.next(), element))
 | 
						|
          return false;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The hash is just that of the element.
 | 
						|
     *
 | 
						|
     * @return The hashcode of the element.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return hashCode(element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returning an array is simple.
 | 
						|
     *
 | 
						|
     * @return An array containing the element.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return new Object[] {element};
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obvious string.
 | 
						|
     *
 | 
						|
     * @return The string surrounded by enclosing
 | 
						|
     *         square brackets.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "[" + element + "]";
 | 
						|
    }
 | 
						|
  } // class SingletonSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtain an immutable List consisting of a single element. The return value
 | 
						|
   * of this method is Serializable, and implements RandomAccess.
 | 
						|
   *
 | 
						|
   * @param o the single element
 | 
						|
   * @return an immutable List containing only o
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   * @since 1.3
 | 
						|
   */
 | 
						|
  public static <T> List<T> singletonList(T o)
 | 
						|
  {
 | 
						|
    return new SingletonList<T>(o);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #singletonList(Object)}. This class name
 | 
						|
   * is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SingletonList<T> extends AbstractList<T>
 | 
						|
    implements Serializable, RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 3093736618740652951L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The single element.
 | 
						|
     * @serial the singleton
 | 
						|
     */
 | 
						|
    private final T element;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Construct a singleton.
 | 
						|
     * @param o the element
 | 
						|
     */
 | 
						|
    SingletonList(T o)
 | 
						|
    {
 | 
						|
      element = o;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size: always 1!
 | 
						|
     * @return 1.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only index 0 is valid.
 | 
						|
     * @param index The index of the element
 | 
						|
     *        to retrieve.
 | 
						|
     * @return The singleton's element if the
 | 
						|
     *         index is 0.
 | 
						|
     * @throws IndexOutOfBoundsException if
 | 
						|
     *         index is not 0.
 | 
						|
     */
 | 
						|
    public T get(int index)
 | 
						|
    {
 | 
						|
      if (index == 0)
 | 
						|
        return element;
 | 
						|
      throw new IndexOutOfBoundsException();
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractList.
 | 
						|
    /**
 | 
						|
     * The set only contains one element.
 | 
						|
     *
 | 
						|
     * @param o The object to search for.
 | 
						|
     * @return <code>true</code> if o == the singleton element.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return equals(o, element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This is true if the other collection only contains the element.
 | 
						|
     *
 | 
						|
     * @param c A collection to compare against this singleton.
 | 
						|
     * @return <code>true</code> if c only contains either no elements or
 | 
						|
     *         elements equal to the element in this singleton.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      Iterator<?> i = c.iterator();
 | 
						|
      int pos = c.size();
 | 
						|
      while (--pos >= 0)
 | 
						|
        if (! equals(i.next(), element))
 | 
						|
          return false;
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Speed up the hashcode computation.
 | 
						|
     *
 | 
						|
     * @return The hashcode of the list, based
 | 
						|
     *         on the hashcode of the singleton element.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return 31 + hashCode(element);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Either the list has it or not.
 | 
						|
     *
 | 
						|
     * @param o The object to find the first index of.
 | 
						|
     * @return 0 if o is the singleton element, -1 if not.
 | 
						|
     */
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      return equals(o, element) ? 0 : -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Either the list has it or not.
 | 
						|
     *
 | 
						|
     * @param o The object to find the last index of.
 | 
						|
     * @return 0 if o is the singleton element, -1 if not.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      return equals(o, element) ? 0 : -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sublists are limited in scope.
 | 
						|
     *
 | 
						|
     * @param from The starting bound for the sublist.
 | 
						|
     * @param to The ending bound for the sublist.
 | 
						|
     * @return Either an empty list if both bounds are
 | 
						|
     *         0 or 1, or this list if the bounds are 0 and 1.
 | 
						|
     * @throws IllegalArgumentException if <code>from > to</code>
 | 
						|
     * @throws IndexOutOfBoundsException if either bound is greater
 | 
						|
     *         than 1.
 | 
						|
     */
 | 
						|
    public List<T> subList(int from, int to)
 | 
						|
    {
 | 
						|
      if (from == to && (to == 0 || to == 1))
 | 
						|
        return emptyList();
 | 
						|
      if (from == 0 && to == 1)
 | 
						|
        return this;
 | 
						|
      if (from > to)
 | 
						|
        throw new IllegalArgumentException();
 | 
						|
      throw new IndexOutOfBoundsException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returning an array is simple.
 | 
						|
     *
 | 
						|
     * @return An array containing the element.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return new Object[] {element};
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obvious string.
 | 
						|
     *
 | 
						|
     * @return The string surrounded by enclosing
 | 
						|
     *         square brackets.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "[" + element + "]";
 | 
						|
    }
 | 
						|
  } // class SingletonList
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtain an immutable Map consisting of a single key-value pair.
 | 
						|
   * The return value of this method is Serializable.
 | 
						|
   *
 | 
						|
   * @param key the single key
 | 
						|
   * @param value the single value
 | 
						|
   * @return an immutable Map containing only the single key-value pair
 | 
						|
   * @see Serializable
 | 
						|
   * @since 1.3
 | 
						|
   */
 | 
						|
  public static <K, V> Map<K, V> singletonMap(K key, V value)
 | 
						|
  {
 | 
						|
    return new SingletonMap<K, V>(key, value);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #singletonMap(Object, Object)}. This class
 | 
						|
   * name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SingletonMap<K, V> extends AbstractMap<K, V>
 | 
						|
    implements Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -6979724477215052911L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The single key.
 | 
						|
     * @serial the singleton key
 | 
						|
     */
 | 
						|
    private final K k;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The corresponding value.
 | 
						|
     * @serial the singleton value
 | 
						|
     */
 | 
						|
    private final V v;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the entry set.
 | 
						|
     */
 | 
						|
    private transient Set<Map.Entry<K, V>> entries;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Construct a singleton.
 | 
						|
     * @param key the key
 | 
						|
     * @param value the value
 | 
						|
     */
 | 
						|
    SingletonMap(K key, V value)
 | 
						|
    {
 | 
						|
      k = key;
 | 
						|
      v = value;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * There is a single immutable entry.
 | 
						|
     *
 | 
						|
     * @return A singleton containing the map entry.
 | 
						|
     */
 | 
						|
    public Set<Map.Entry<K, V>> entrySet()
 | 
						|
    {
 | 
						|
      if (entries == null)
 | 
						|
        {
 | 
						|
          Map.Entry<K,V> entry = new AbstractMap.SimpleEntry<K, V>(k, v)
 | 
						|
          {
 | 
						|
            /**
 | 
						|
             * Sets the value of the map entry to the supplied value.
 | 
						|
             * An exception is always thrown, as the map is immutable.
 | 
						|
             *
 | 
						|
             * @param o The new value.
 | 
						|
             * @return The old value.
 | 
						|
             * @throws UnsupportedOperationException as setting the value
 | 
						|
             *         is not supported.
 | 
						|
             */
 | 
						|
            public V setValue(V o)
 | 
						|
            {
 | 
						|
              throw new UnsupportedOperationException();
 | 
						|
            }
 | 
						|
          };
 | 
						|
          entries = singleton(entry);
 | 
						|
        }
 | 
						|
      return entries;
 | 
						|
    }
 | 
						|
 | 
						|
    // The remaining methods are optional, but provide a performance
 | 
						|
    // advantage by not allocating unnecessary iterators in AbstractMap.
 | 
						|
    /**
 | 
						|
     * Single entry.
 | 
						|
     *
 | 
						|
     * @param key The key to look for.
 | 
						|
     * @return <code>true</code> if the key is the same as the one used by
 | 
						|
     *         this map.
 | 
						|
     */
 | 
						|
    public boolean containsKey(Object key)
 | 
						|
    {
 | 
						|
      return equals(key, k);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Single entry.
 | 
						|
     *
 | 
						|
     * @param value The value to look for.
 | 
						|
     * @return <code>true</code> if the value is the same as the one used by
 | 
						|
     *         this map.
 | 
						|
     */
 | 
						|
    public boolean containsValue(Object value)
 | 
						|
    {
 | 
						|
      return equals(value, v);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Single entry.
 | 
						|
     *
 | 
						|
     * @param key The key of the value to be retrieved.
 | 
						|
     * @return The singleton value if the key is the same as the
 | 
						|
     *         singleton key, null otherwise.
 | 
						|
     */
 | 
						|
    public V get(Object key)
 | 
						|
    {
 | 
						|
      return equals(key, k) ? v : null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Calculate the hashcode directly.
 | 
						|
     *
 | 
						|
     * @return The hashcode computed from the singleton key
 | 
						|
     *         and the singleton value.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return hashCode(k) ^ hashCode(v);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the keyset.
 | 
						|
     *
 | 
						|
     * @return A singleton containing the key.
 | 
						|
     */
 | 
						|
    public Set<K> keySet()
 | 
						|
    {
 | 
						|
      if (keys == null)
 | 
						|
        keys = singleton(k);
 | 
						|
      return keys;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The size: always 1!
 | 
						|
     *
 | 
						|
     * @return 1.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the values. Technically, a singleton, while more specific than
 | 
						|
     * a general Collection, will work. Besides, that's what the JDK uses!
 | 
						|
     *
 | 
						|
     * @return A singleton containing the value.
 | 
						|
     */
 | 
						|
    public Collection<V> values()
 | 
						|
    {
 | 
						|
      if (values == null)
 | 
						|
        values = singleton(v);
 | 
						|
      return values;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obvious string.
 | 
						|
     *
 | 
						|
     * @return A string containing the string representations of the key
 | 
						|
     *         and its associated value.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return "{" + k + "=" + v + "}";
 | 
						|
    }
 | 
						|
  } // class SingletonMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sort a list according to the natural ordering of its elements. The list
 | 
						|
   * must be modifiable, but can be of fixed size. The sort algorithm is
 | 
						|
   * precisely that used by Arrays.sort(Object[]), which offers guaranteed
 | 
						|
   * nlog(n) performance. This implementation dumps the list into an array,
 | 
						|
   * sorts the array, and then iterates over the list setting each element from
 | 
						|
   * the array.
 | 
						|
   *
 | 
						|
   * @param l the List to sort (<code>null</code> not permitted)
 | 
						|
   * @throws ClassCastException if some items are not mutually comparable
 | 
						|
   * @throws UnsupportedOperationException if the List is not modifiable
 | 
						|
   * @throws NullPointerException if the list is <code>null</code>, or contains
 | 
						|
   *     some element that is <code>null</code>.
 | 
						|
   * @see Arrays#sort(Object[])
 | 
						|
   */
 | 
						|
  public static <T extends Comparable<? super T>> void sort(List<T> l)
 | 
						|
  {
 | 
						|
    sort(l, null);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sort a list according to a specified Comparator. The list must be
 | 
						|
   * modifiable, but can be of fixed size. The sort algorithm is precisely that
 | 
						|
   * used by Arrays.sort(Object[], Comparator), which offers guaranteed
 | 
						|
   * nlog(n) performance. This implementation dumps the list into an array,
 | 
						|
   * sorts the array, and then iterates over the list setting each element from
 | 
						|
   * the array.
 | 
						|
   *
 | 
						|
   * @param l the List to sort (<code>null</code> not permitted)
 | 
						|
   * @param c the Comparator specifying the ordering for the elements, or
 | 
						|
   *        <code>null</code> for natural ordering
 | 
						|
   * @throws ClassCastException if c will not compare some pair of items
 | 
						|
   * @throws UnsupportedOperationException if the List is not modifiable
 | 
						|
   * @throws NullPointerException if the List is <code>null</code> or
 | 
						|
   *         <code>null</code> is compared by natural ordering (only possible
 | 
						|
   *         when c is <code>null</code>)
 | 
						|
   *
 | 
						|
   * @see Arrays#sort(Object[], Comparator)
 | 
						|
   */
 | 
						|
  public static <T> void sort(List<T> l, Comparator<? super T> c)
 | 
						|
  {
 | 
						|
    T[] a = (T[]) l.toArray();
 | 
						|
    Arrays.sort(a, c);
 | 
						|
    ListIterator<T> i = l.listIterator();
 | 
						|
    for (int pos = 0, alen = a.length;  pos < alen;  pos++)
 | 
						|
      {
 | 
						|
        i.next();
 | 
						|
        i.set(a[pos]);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Swaps the elements at the specified positions within the list. Equal
 | 
						|
   * positions have no effect.
 | 
						|
   *
 | 
						|
   * @param l the list to work on
 | 
						|
   * @param i the first index to swap
 | 
						|
   * @param j the second index
 | 
						|
   * @throws UnsupportedOperationException if list.set is not supported
 | 
						|
   * @throws IndexOutOfBoundsException if either i or j is < 0 or >=
 | 
						|
   *         list.size()
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public static void swap(List<?> l, int i, int j)
 | 
						|
  {
 | 
						|
    List<Object> list = (List<Object>) l;
 | 
						|
    list.set(i, list.set(j, list.get(i)));
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) collection wrapper backed by the
 | 
						|
   * given collection. Notice that element access through the iterators
 | 
						|
   * is thread-safe, but if the collection can be structurally modified
 | 
						|
   * (adding or removing elements) then you should synchronize around the
 | 
						|
   * iteration to avoid non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * Collection c = Collections.synchronizedCollection(new Collection(...));
 | 
						|
   * ...
 | 
						|
   * synchronized (c)
 | 
						|
   *   {
 | 
						|
   *     Iterator i = c.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * Since the collection might be a List or a Set, and those have incompatible
 | 
						|
   * equals and hashCode requirements, this relies on Object's implementation
 | 
						|
   * rather than passing those calls on to the wrapped collection. The returned
 | 
						|
   * Collection implements Serializable, but can only be serialized if
 | 
						|
   * the collection it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param c the collection to wrap
 | 
						|
   * @return a synchronized view of the collection
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Collection<T> synchronizedCollection(Collection<T> c)
 | 
						|
  {
 | 
						|
    return new SynchronizedCollection<T>(c);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedCollection(Collection)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   * Package visible, so that collections such as the one for
 | 
						|
   * Hashtable.values() can specify which object to synchronize on.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  static class SynchronizedCollection<T>
 | 
						|
    implements Collection<T>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 3053995032091335093L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped collection. Package visible for use by subclasses.
 | 
						|
     * @serial the real collection
 | 
						|
     */
 | 
						|
    final Collection<T> c;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The object to synchronize on.  When an instance is created via public
 | 
						|
     * methods, it will be this; but other uses like SynchronizedMap.values()
 | 
						|
     * must specify another mutex. Package visible for use by subclasses.
 | 
						|
     * @serial the lock
 | 
						|
     */
 | 
						|
    final Object mutex;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given collection.
 | 
						|
     * @param c the collection to wrap
 | 
						|
     * @throws NullPointerException if c is null
 | 
						|
     */
 | 
						|
    SynchronizedCollection(Collection<T> c)
 | 
						|
    {
 | 
						|
      this.c = c;
 | 
						|
      mutex = this;
 | 
						|
      if (c == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the
 | 
						|
     * collection.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param c the collection
 | 
						|
     */
 | 
						|
    SynchronizedCollection(Object sync, Collection<T> c)
 | 
						|
    {
 | 
						|
      this.c = c;
 | 
						|
      mutex = sync;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the object to the underlying collection, first
 | 
						|
     * obtaining a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @param o The object to add.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result
 | 
						|
     *         of this action.
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *         support the add operation.
 | 
						|
     * @throws ClassCastException if o cannot be added to this collection due
 | 
						|
     *         to its type.
 | 
						|
     * @throws NullPointerException if o is null and this collection doesn't
 | 
						|
     *         support the addition of null values.
 | 
						|
     * @throws IllegalArgumentException if o cannot be added to this
 | 
						|
     *         collection for some other reason.
 | 
						|
     */
 | 
						|
    public boolean add(T o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.add(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the objects in col to the underlying collection, first
 | 
						|
     * obtaining a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @param col The collection to take the new objects from.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result
 | 
						|
     *          of this action.
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *         support the addAll operation.
 | 
						|
     * @throws ClassCastException if some element of col cannot be added to this
 | 
						|
     *         collection due to its type.
 | 
						|
     * @throws NullPointerException if some element of col is null and this
 | 
						|
     *         collection does not support the addition of null values.
 | 
						|
     * @throws NullPointerException if col itself is null.
 | 
						|
     * @throws IllegalArgumentException if some element of col cannot be added
 | 
						|
     *         to this collection for some other reason.
 | 
						|
     */
 | 
						|
    public boolean addAll(Collection<? extends T> col)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.addAll(col);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all objects from the underlying collection,
 | 
						|
     * first obtaining a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *         support the clear operation.
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          c.clear();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Checks for the existence of o within the underlying
 | 
						|
     * collection, first obtaining a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @param o the element to look for.
 | 
						|
     * @return <code>true</code> if this collection contains at least one
 | 
						|
     *         element e such that <code>o == null ? e == null : o.equals(e)</code>.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid type for this
 | 
						|
     *         collection.
 | 
						|
     * @throws NullPointerException if o is null and this collection doesn't
 | 
						|
     *         support null values.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.contains(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Checks for the existence of each object in cl
 | 
						|
     * within the underlying collection, first obtaining
 | 
						|
     * a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @param c1 the collection to test for.
 | 
						|
     * @return <code>true</code> if for every element o in c, contains(o)
 | 
						|
     *         would return <code>true</code>.
 | 
						|
     * @throws ClassCastException if the type of any element in cl is not a valid
 | 
						|
     *         type for this collection.
 | 
						|
     * @throws NullPointerException if some element of cl is null and this
 | 
						|
     *         collection does not support null values.
 | 
						|
     * @throws NullPointerException if cl itself is null.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c1)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.containsAll(c1);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if there are no objects in the underlying
 | 
						|
     * collection.  A lock on the mutex is obtained before the
 | 
						|
     * check is performed.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if this collection contains no elements.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.isEmpty();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a synchronized iterator wrapper around the underlying
 | 
						|
     * collection's iterator.  A lock on the mutex is obtained before
 | 
						|
     * retrieving the collection's iterator.
 | 
						|
     *
 | 
						|
     * @return An iterator over the elements in the underlying collection,
 | 
						|
     *         which returns each element in any order.
 | 
						|
     */
 | 
						|
    public Iterator<T> iterator()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedIterator<T>(mutex, c.iterator());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the specified object from the underlying collection,
 | 
						|
     * first obtaining a lock on the mutex.
 | 
						|
     *
 | 
						|
     * @param o The object to remove.
 | 
						|
     * @return <code>true</code> if the collection changed as a result of this call, that is,
 | 
						|
     *         if the collection contained at least one occurrence of o.
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *         support the remove operation.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid type
 | 
						|
     *         for this collection.
 | 
						|
     * @throws NullPointerException if o is null and the collection doesn't
 | 
						|
     *         support null values.
 | 
						|
     */
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.remove(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all elements, e, of the underlying
 | 
						|
     * collection for which <code>col.contains(e)</code>
 | 
						|
     * returns <code>true</code>.  A lock on the mutex is obtained
 | 
						|
     * before the operation proceeds.
 | 
						|
     *
 | 
						|
     * @param col The collection of objects to be removed.
 | 
						|
     * @return <code>true</code> if this collection was modified as a result of this call.
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *   support the removeAll operation.
 | 
						|
     * @throws ClassCastException if the type of any element in c is not a valid
 | 
						|
     *   type for this collection.
 | 
						|
     * @throws NullPointerException if some element of c is null and this
 | 
						|
     *   collection does not support removing null values.
 | 
						|
     * @throws NullPointerException if c itself is null.
 | 
						|
     */
 | 
						|
    public boolean removeAll(Collection<?> col)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.removeAll(col);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retains all elements, e, of the underlying
 | 
						|
     * collection for which <code>col.contains(e)</code>
 | 
						|
     * returns <code>true</code>.  That is, every element that doesn't
 | 
						|
     * exist in col is removed.  A lock on the mutex is obtained
 | 
						|
     * before the operation proceeds.
 | 
						|
     *
 | 
						|
     * @param col The collection of objects to be removed.
 | 
						|
     * @return <code>true</code> if this collection was modified as a result of this call.
 | 
						|
     * @throws UnsupportedOperationException if this collection does not
 | 
						|
     *   support the removeAll operation.
 | 
						|
     * @throws ClassCastException if the type of any element in c is not a valid
 | 
						|
     *   type for this collection.
 | 
						|
     * @throws NullPointerException if some element of c is null and this
 | 
						|
     *   collection does not support removing null values.
 | 
						|
     * @throws NullPointerException if c itself is null.
 | 
						|
     */
 | 
						|
    public boolean retainAll(Collection<?> col)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.retainAll(col);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the size of the underlying collection.
 | 
						|
     * A lock on the mutex is obtained before the collection
 | 
						|
     * is accessed.
 | 
						|
     *
 | 
						|
     * @return The size of the collection.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.size();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns an array containing each object within the underlying
 | 
						|
     * collection.  A lock is obtained on the mutex before the collection
 | 
						|
     * is accessed.
 | 
						|
     *
 | 
						|
     * @return An array of objects, matching the collection in size.  The
 | 
						|
     *         elements occur in any order.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.toArray();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copies the elements in the underlying collection to the supplied
 | 
						|
     * array.  If <code>a.length < size()</code>, a new array of the
 | 
						|
     * same run-time type is created, with a size equal to that of
 | 
						|
     * the collection.  If <code>a.length > size()</code>, then the
 | 
						|
     * elements from 0 to <code>size() - 1</code> contain the elements
 | 
						|
     * from this collection.  The following element is set to null
 | 
						|
     * to indicate the end of the collection objects.  However, this
 | 
						|
     * only makes a difference if null is not a permitted value within
 | 
						|
     * the collection.
 | 
						|
     * Before the copying takes place, a lock is obtained on the mutex.
 | 
						|
     *
 | 
						|
     * @param a An array to copy elements to.
 | 
						|
     * @return An array containing the elements of the underlying collection.
 | 
						|
     * @throws ArrayStoreException if the type of any element of the
 | 
						|
     *         collection is not a subtype of the element type of a.
 | 
						|
     */
 | 
						|
    public <E> E[] toArray(E[] a)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.toArray(a);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a string representation of the underlying collection.
 | 
						|
     * A lock is obtained on the mutex before the string is created.
 | 
						|
     *
 | 
						|
     * @return A string representation of the collection.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.toString();
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedCollection
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of the various iterator methods in the
 | 
						|
   * synchronized classes. These iterators must "sync" on the same object
 | 
						|
   * as the collection they iterate over.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class SynchronizedIterator<T> implements Iterator<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The object to synchronize on. Package visible for use by subclass.
 | 
						|
     */
 | 
						|
    final Object mutex;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped iterator.
 | 
						|
     */
 | 
						|
    private final Iterator<T> i;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper, with the specified sync.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param i the wrapped iterator
 | 
						|
     */
 | 
						|
    SynchronizedIterator(Object sync, Iterator<T> i)
 | 
						|
    {
 | 
						|
      this.i = i;
 | 
						|
      mutex = sync;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the next object in the underlying collection.
 | 
						|
     * A lock is obtained on the mutex before the collection is accessed.
 | 
						|
     *
 | 
						|
     * @return The next object in the collection.
 | 
						|
     * @throws NoSuchElementException if there are no more elements
 | 
						|
     */
 | 
						|
    public T next()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return i.next();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if objects can still be retrieved from the iterator
 | 
						|
     * using <code>next()</code>.  A lock is obtained on the mutex before
 | 
						|
     * the collection is accessed.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if at least one element is still to be returned by
 | 
						|
     *         <code>next()</code>.
 | 
						|
     */
 | 
						|
    public boolean hasNext()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return i.hasNext();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the object that was last returned by <code>next()</code>
 | 
						|
     * from the underlying collection.  Only one call to this method is
 | 
						|
     * allowed per call to the <code>next()</code> method, and it does
 | 
						|
     * not affect the value that will be returned by <code>next()</code>.
 | 
						|
     * Thus, if element n was retrieved from the collection by
 | 
						|
     * <code>next()</code>, it is this element that gets removed.
 | 
						|
     * Regardless of whether this takes place or not, element n+1 is
 | 
						|
     * still returned on the subsequent <code>next()</code> call.
 | 
						|
     *
 | 
						|
     * @throws IllegalStateException if next has not yet been called or remove
 | 
						|
     *         has already been called since the last call to next.
 | 
						|
     * @throws UnsupportedOperationException if this Iterator does not support
 | 
						|
     *         the remove operation.
 | 
						|
     */
 | 
						|
    public void remove()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          i.remove();
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) list wrapper backed by the
 | 
						|
   * given list. Notice that element access through the iterators
 | 
						|
   * is thread-safe, but if the list can be structurally modified
 | 
						|
   * (adding or removing elements) then you should synchronize around the
 | 
						|
   * iteration to avoid non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * List l = Collections.synchronizedList(new List(...));
 | 
						|
   * ...
 | 
						|
   * synchronized (l)
 | 
						|
   *   {
 | 
						|
   *     Iterator i = l.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * The returned List implements Serializable, but can only be serialized if
 | 
						|
   * the list it wraps is likewise Serializable. In addition, if the wrapped
 | 
						|
   * list implements RandomAccess, this does too.
 | 
						|
   *
 | 
						|
   * @param l the list to wrap
 | 
						|
   * @return a synchronized view of the list
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   */
 | 
						|
  public static <T> List<T> synchronizedList(List<T> l)
 | 
						|
  {
 | 
						|
    if (l instanceof RandomAccess)
 | 
						|
      return new SynchronizedRandomAccessList<T>(l);
 | 
						|
    return new SynchronizedList<T>(l);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedList(List)} for sequential
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability. Package visible, so that lists such as Vector.subList()
 | 
						|
   * can specify which object to synchronize on.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  static class SynchronizedList<T> extends SynchronizedCollection<T>
 | 
						|
    implements List<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -7754090372962971524L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped list; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting. Package visible for use by subclass.
 | 
						|
     * @serial the wrapped list
 | 
						|
     */
 | 
						|
    final List<T> list;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    SynchronizedList(List<T> l)
 | 
						|
    {
 | 
						|
      super(l);
 | 
						|
      list = l;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the list.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param l the list
 | 
						|
     */
 | 
						|
    SynchronizedList(Object sync, List<T> l)
 | 
						|
    {
 | 
						|
      super(sync, l);
 | 
						|
      list = l;
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Insert an element into the underlying list at a given position (optional
 | 
						|
   * operation).  This shifts all existing elements from that position to the
 | 
						|
   * end one index to the right. This version of add has no return, since it is
 | 
						|
   * assumed to always succeed if there is no exception.  Before the
 | 
						|
   * addition takes place, a lock is obtained on the mutex.
 | 
						|
   *
 | 
						|
   * @param index the location to insert the item
 | 
						|
   * @param o the object to insert
 | 
						|
   * @throws UnsupportedOperationException if this list does not support the
 | 
						|
   *         add operation
 | 
						|
   * @throws IndexOutOfBoundsException if index < 0 || index > size()
 | 
						|
   * @throws ClassCastException if o cannot be added to this list due to its
 | 
						|
   *         type
 | 
						|
   * @throws IllegalArgumentException if o cannot be added to this list for
 | 
						|
   *         some other reason
 | 
						|
   * @throws NullPointerException if o is null and this list doesn't support
 | 
						|
   *         the addition of null values.
 | 
						|
   */
 | 
						|
    public void add(int index, T o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          list.add(index, o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Add the contents of a collection to the underlying list at the given
 | 
						|
   * index (optional operation).  If the list imposes restraints on what
 | 
						|
   * can be inserted, such as no null elements, this should be documented.
 | 
						|
   * A lock is obtained on the mutex before any of the elements are added.
 | 
						|
   *
 | 
						|
   * @param index the index at which to insert
 | 
						|
   * @param c the collection to add
 | 
						|
   * @return <code>true</code>, as defined by Collection for a modified list
 | 
						|
   * @throws UnsupportedOperationException if this list does not support the
 | 
						|
   *         add operation
 | 
						|
   * @throws ClassCastException if o cannot be added to this list due to its
 | 
						|
   *         type
 | 
						|
   * @throws IllegalArgumentException if o cannot be added to this list for
 | 
						|
   *         some other reason
 | 
						|
   * @throws NullPointerException if o is null and this list doesn't support
 | 
						|
   *         the addition of null values.
 | 
						|
   */
 | 
						|
    public boolean addAll(int index, Collection<? extends T> c)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.addAll(index, c);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
   /**
 | 
						|
    * Tests whether the underlying list is equal to the supplied object.
 | 
						|
    * The object is deemed to be equal if it is also a <code>List</code>
 | 
						|
    * of equal size and with the same elements (i.e. each element, e1,
 | 
						|
    * in list, l1, and each element, e2, in l2, must return <code>true</code> for
 | 
						|
    * <code>e1 == null ? e2 == null : e1.equals(e2)</code>.  Before the
 | 
						|
    * comparison is made, a lock is obtained on the mutex.
 | 
						|
    *
 | 
						|
    * @param o The object to test for equality with the underlying list.
 | 
						|
    * @return <code>true</code> if o is equal to the underlying list under the above
 | 
						|
    *         definition.
 | 
						|
    */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.equals(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the object at the specified index.  A lock
 | 
						|
     * is obtained on the mutex before the list is accessed.
 | 
						|
     *
 | 
						|
     * @param index the index of the element to be returned
 | 
						|
     * @return the element at index index in this list
 | 
						|
     * @throws IndexOutOfBoundsException if index < 0 || index >= size()
 | 
						|
     */
 | 
						|
    public T get(int index)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.get(index);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains a hashcode for the underlying list, first obtaining
 | 
						|
     * a lock on the mutex.  The calculation of the hashcode is
 | 
						|
     * detailed in the documentation for the <code>List</code>
 | 
						|
     * interface.
 | 
						|
     *
 | 
						|
     * @return The hashcode of the underlying list.
 | 
						|
     * @see List#hashCode()
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.hashCode();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the first index at which a given object is to be found in the
 | 
						|
     * underlying list.  A lock is obtained on the mutex before the list is
 | 
						|
     * accessed.
 | 
						|
     *
 | 
						|
     * @param o the object to search for
 | 
						|
     * @return the least integer n such that <code>o == null ? get(n) == null :
 | 
						|
     *         o.equals(get(n))</code>, or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for this list.
 | 
						|
     * @throws NullPointerException if o is null and this
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.indexOf(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the last index at which a given object is to be found in this
 | 
						|
     * underlying list.  A lock is obtained on the mutex before the list
 | 
						|
     * is accessed.
 | 
						|
     *
 | 
						|
     * @return the greatest integer n such that <code>o == null ? get(n) == null
 | 
						|
     *         : o.equals(get(n))</code>, or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for this list.
 | 
						|
     * @throws NullPointerException if o is null and this
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.lastIndexOf(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves a synchronized wrapper around the underlying list's
 | 
						|
     * list iterator.  A lock is obtained on the mutex before the
 | 
						|
     * list iterator is retrieved.
 | 
						|
     *
 | 
						|
     * @return A list iterator over the elements in the underlying list.
 | 
						|
     *         The list iterator allows additional list-specific operations
 | 
						|
     *         to be performed, in addition to those supplied by the
 | 
						|
     *         standard iterator.
 | 
						|
     */
 | 
						|
    public ListIterator<T> listIterator()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedListIterator<T>(mutex, list.listIterator());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves a synchronized wrapper around the underlying list's
 | 
						|
     * list iterator.  A lock is obtained on the mutex before the
 | 
						|
     * list iterator is retrieved.  The iterator starts at the
 | 
						|
     * index supplied, leading to the element at that index being
 | 
						|
     * the first one returned by <code>next()</code>.  Calling
 | 
						|
     * <code>previous()</code> from this initial position returns
 | 
						|
     * index - 1.
 | 
						|
     *
 | 
						|
     * @param index the position, between 0 and size() inclusive, to begin the
 | 
						|
     *        iteration from
 | 
						|
     * @return A list iterator over the elements in the underlying list.
 | 
						|
     *         The list iterator allows additional list-specific operations
 | 
						|
     *         to be performed, in addition to those supplied by the
 | 
						|
     *         standard iterator.
 | 
						|
     * @throws IndexOutOfBoundsException if index < 0 || index > size()
 | 
						|
     */
 | 
						|
    public ListIterator<T> listIterator(int index)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedListIterator<T>(mutex,
 | 
						|
                                                 list.listIterator(index));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Remove the element at a given position in the underlying list (optional
 | 
						|
     * operation).  All remaining elements are shifted to the left to fill the gap.
 | 
						|
     * A lock on the mutex is obtained before the element is removed.
 | 
						|
     *
 | 
						|
     * @param index the position within the list of the object to remove
 | 
						|
     * @return the object that was removed
 | 
						|
     * @throws UnsupportedOperationException if this list does not support the
 | 
						|
     *         remove operation
 | 
						|
     * @throws IndexOutOfBoundsException if index < 0 || index >= size()
 | 
						|
     */
 | 
						|
    public T remove(int index)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.remove(index);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Replace an element of the underlying list with another object (optional
 | 
						|
   * operation).  A lock is obtained on the mutex before the element is
 | 
						|
   * replaced.
 | 
						|
   *
 | 
						|
   * @param index the position within this list of the element to be replaced
 | 
						|
   * @param o the object to replace it with
 | 
						|
   * @return the object that was replaced
 | 
						|
   * @throws UnsupportedOperationException if this list does not support the
 | 
						|
   *         set operation.
 | 
						|
   * @throws IndexOutOfBoundsException if index < 0 || index >= size()
 | 
						|
   * @throws ClassCastException if o cannot be added to this list due to its
 | 
						|
   *         type
 | 
						|
   * @throws IllegalArgumentException if o cannot be added to this list for
 | 
						|
   *         some other reason
 | 
						|
   * @throws NullPointerException if o is null and this
 | 
						|
   *         list does not support null values.
 | 
						|
   */
 | 
						|
    public T set(int index, T o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return list.set(index, o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain a List view of a subsection of the underlying list, from fromIndex
 | 
						|
     * (inclusive) to toIndex (exclusive). If the two indices are equal, the
 | 
						|
     * sublist is empty. The returned list should be modifiable if and only
 | 
						|
     * if this list is modifiable. Changes to the returned list should be
 | 
						|
     * reflected in this list. If this list is structurally modified in
 | 
						|
     * any way other than through the returned list, the result of any subsequent
 | 
						|
     * operations on the returned list is undefined.  A lock is obtained
 | 
						|
     * on the mutex before the creation of the sublist.  The returned list
 | 
						|
     * is also synchronized, using the same mutex.
 | 
						|
     *
 | 
						|
     * @param fromIndex the index that the returned list should start from
 | 
						|
     *        (inclusive)
 | 
						|
     * @param toIndex the index that the returned list should go to (exclusive)
 | 
						|
     * @return a List backed by a subsection of this list
 | 
						|
     * @throws IndexOutOfBoundsException if fromIndex < 0
 | 
						|
     *         || toIndex > size() || fromIndex > toIndex
 | 
						|
     */
 | 
						|
    public List<T> subList(int fromIndex, int toIndex)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedList<T>(mutex,
 | 
						|
                                         list.subList(fromIndex, toIndex));
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedList(List)} for random-access
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SynchronizedRandomAccessList<T>
 | 
						|
    extends SynchronizedList<T> implements RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1530674583602358482L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    SynchronizedRandomAccessList(List<T> l)
 | 
						|
    {
 | 
						|
      super(l);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the
 | 
						|
     * collection.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param l the list
 | 
						|
     */
 | 
						|
    SynchronizedRandomAccessList(Object sync, List<T> l)
 | 
						|
    {
 | 
						|
      super(sync, l);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain a List view of a subsection of the underlying list, from fromIndex
 | 
						|
     * (inclusive) to toIndex (exclusive). If the two indices are equal, the
 | 
						|
     * sublist is empty. The returned list should be modifiable if and only
 | 
						|
     * if this list is modifiable. Changes to the returned list should be
 | 
						|
     * reflected in this list. If this list is structurally modified in
 | 
						|
     * any way other than through the returned list, the result of any subsequent
 | 
						|
     * operations on the returned list is undefined.    A lock is obtained
 | 
						|
     * on the mutex before the creation of the sublist.  The returned list
 | 
						|
     * is also synchronized, using the same mutex.  Random accessibility
 | 
						|
     * is also extended to the new list.
 | 
						|
     *
 | 
						|
     * @param fromIndex the index that the returned list should start from
 | 
						|
     *        (inclusive)
 | 
						|
     * @param toIndex the index that the returned list should go to (exclusive)
 | 
						|
     * @return a List backed by a subsection of this list
 | 
						|
     * @throws IndexOutOfBoundsException if fromIndex < 0
 | 
						|
     *         || toIndex > size() || fromIndex > toIndex
 | 
						|
     */
 | 
						|
    public List<T> subList(int fromIndex, int toIndex)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedRandomAccessList<T>(mutex,
 | 
						|
                                                     list.subList(fromIndex,
 | 
						|
                                                                  toIndex));
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedRandomAccessList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link SynchronizedList#listIterator()}. This
 | 
						|
   * iterator must "sync" on the same object as the list it iterates over.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SynchronizedListIterator<T>
 | 
						|
    extends SynchronizedIterator<T> implements ListIterator<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The wrapped iterator, stored both here and in the superclass to
 | 
						|
     * avoid excessive casting.
 | 
						|
     */
 | 
						|
    private final ListIterator<T> li;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper, with the specified sync.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param li the wrapped iterator
 | 
						|
     */
 | 
						|
    SynchronizedListIterator(Object sync, ListIterator<T> li)
 | 
						|
    {
 | 
						|
      super(sync, li);
 | 
						|
      this.li = li;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Insert an element into the underlying list at the current position of
 | 
						|
     * the iterator (optional operation). The element is inserted in between
 | 
						|
     * the element that would be returned by <code>previous()</code> and the
 | 
						|
     * element that would be returned by <code>next()</code>. After the
 | 
						|
     * insertion, a subsequent call to next is unaffected, but
 | 
						|
     * a call to previous returns the item that was added. The values returned
 | 
						|
     * by nextIndex() and previousIndex() are incremented.  A lock is obtained
 | 
						|
     * on the mutex before the addition takes place.
 | 
						|
     *
 | 
						|
     * @param o the object to insert into the list
 | 
						|
     * @throws ClassCastException if the object is of a type which cannot be added
 | 
						|
     *         to this list.
 | 
						|
     * @throws IllegalArgumentException if some other aspect of the object stops
 | 
						|
     *         it being added to this list.
 | 
						|
     * @throws UnsupportedOperationException if this ListIterator does not
 | 
						|
     *         support the add operation.
 | 
						|
     */
 | 
						|
    public void add(T o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          li.add(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether there are elements remaining in the underlying list
 | 
						|
     * in the reverse direction. In other words, <code>previous()</code>
 | 
						|
     * will not fail with a NoSuchElementException.  A lock is obtained
 | 
						|
     * on the mutex before the check takes place.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if the list continues in the reverse direction
 | 
						|
     */
 | 
						|
    public boolean hasPrevious()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return li.hasPrevious();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
      * Find the index of the element that would be returned by a call to
 | 
						|
      * <code>next()</code>.  If hasNext() returns <code>false</code>, this
 | 
						|
      * returns the list size.  A lock is obtained on the mutex before the
 | 
						|
      * query takes place.
 | 
						|
      *
 | 
						|
      * @return the index of the element that would be returned by next()
 | 
						|
      */
 | 
						|
    public int nextIndex()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return li.nextIndex();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the previous element from the underlying list. Repeated
 | 
						|
     * calls to previous may be used to iterate backwards over the entire list,
 | 
						|
     * or calls to next and previous may be used together to go forwards and
 | 
						|
     * backwards. Alternating calls to next and previous will return the same
 | 
						|
     * element.  A lock is obtained on the mutex before the object is retrieved.
 | 
						|
     *
 | 
						|
     * @return the next element in the list in the reverse direction
 | 
						|
     * @throws NoSuchElementException if there are no more elements
 | 
						|
     */
 | 
						|
    public T previous()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return li.previous();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find the index of the element that would be returned by a call to
 | 
						|
     * previous. If hasPrevious() returns <code>false</code>, this returns -1.
 | 
						|
     * A lock is obtained on the mutex before the query takes place.
 | 
						|
     *
 | 
						|
     * @return the index of the element that would be returned by previous()
 | 
						|
     */
 | 
						|
    public int previousIndex()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return li.previousIndex();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Replace the element last returned by a call to <code>next()</code> or
 | 
						|
     * <code>previous()</code> with a given object (optional operation).  This
 | 
						|
     * method may only be called if neither <code>add()</code> nor
 | 
						|
     * <code>remove()</code> have been called since the last call to
 | 
						|
     * <code>next()</code> or <code>previous</code>.  A lock is obtained
 | 
						|
     * on the mutex before the list is modified.
 | 
						|
     *
 | 
						|
     * @param o the object to replace the element with
 | 
						|
     * @throws ClassCastException the object is of a type which cannot be added
 | 
						|
     *         to this list
 | 
						|
     * @throws IllegalArgumentException some other aspect of the object stops
 | 
						|
     *         it being added to this list
 | 
						|
     * @throws IllegalStateException if neither next or previous have been
 | 
						|
     *         called, or if add or remove has been called since the last call
 | 
						|
     *         to next or previous
 | 
						|
     * @throws UnsupportedOperationException if this ListIterator does not
 | 
						|
     *         support the set operation
 | 
						|
     */
 | 
						|
    public void set(T o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          li.set(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedListIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) map wrapper backed by the given
 | 
						|
   * map. Notice that element access through the collection views and their
 | 
						|
   * iterators are thread-safe, but if the map can be structurally modified
 | 
						|
   * (adding or removing elements) then you should synchronize around the
 | 
						|
   * iteration to avoid non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * Map m = Collections.synchronizedMap(new Map(...));
 | 
						|
   * ...
 | 
						|
   * Set s = m.keySet(); // safe outside a synchronized block
 | 
						|
   * synchronized (m) // synch on m, not s
 | 
						|
   *   {
 | 
						|
   *     Iterator i = s.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * The returned Map implements Serializable, but can only be serialized if
 | 
						|
   * the map it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param m the map to wrap
 | 
						|
   * @return a synchronized view of the map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> Map<K, V> synchronizedMap(Map<K, V> m)
 | 
						|
  {
 | 
						|
    return new SynchronizedMap<K, V>(m);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedMap(Map)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class SynchronizedMap<K, V> implements Map<K, V>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1978198479659022715L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map.
 | 
						|
     * @serial the real map
 | 
						|
     */
 | 
						|
    private final Map<K, V> m;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The object to synchronize on.  When an instance is created via public
 | 
						|
     * methods, it will be this; but other uses like
 | 
						|
     * SynchronizedSortedMap.subMap() must specify another mutex. Package
 | 
						|
     * visible for use by subclass.
 | 
						|
     * @serial the lock
 | 
						|
     */
 | 
						|
    final Object mutex;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the entry set.
 | 
						|
     */
 | 
						|
    private transient Set<Map.Entry<K, V>> entries;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the key set.
 | 
						|
     */
 | 
						|
    private transient Set<K> keys;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the value collection.
 | 
						|
     */
 | 
						|
    private transient Collection<V> values;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     * @param m the map to wrap
 | 
						|
     * @throws NullPointerException if m is null
 | 
						|
     */
 | 
						|
    SynchronizedMap(Map<K, V> m)
 | 
						|
    {
 | 
						|
      this.m = m;
 | 
						|
      mutex = this;
 | 
						|
      if (m == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the map.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param m the map
 | 
						|
     */
 | 
						|
    SynchronizedMap(Object sync, Map<K, V> m)
 | 
						|
    {
 | 
						|
      this.m = m;
 | 
						|
      mutex = sync;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Clears all the entries from the underlying map.  A lock is obtained
 | 
						|
     * on the mutex before the map is cleared.
 | 
						|
     *
 | 
						|
     * @throws UnsupportedOperationException if clear is not supported
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          m.clear();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains a entry for the given key.
 | 
						|
     * A lock is obtained on the mutex before the map is queried.
 | 
						|
     *
 | 
						|
     * @param key the key to search for.
 | 
						|
     * @return <code>true</code> if the underlying map contains the key.
 | 
						|
     * @throws ClassCastException if the key is of an inappropriate type.
 | 
						|
     * @throws NullPointerException if key is <code>null</code> but the map
 | 
						|
     *         does not permit null keys.
 | 
						|
     */
 | 
						|
    public boolean containsKey(Object key)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.containsKey(key);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns <code>true</code> if the underlying map contains at least one entry with the
 | 
						|
   * given value.  In other words, returns <code>true</code> if a value v exists where
 | 
						|
   * <code>(value == null ? v == null : value.equals(v))</code>. This usually
 | 
						|
   * requires linear time.  A lock is obtained on the mutex before the map
 | 
						|
   * is queried.
 | 
						|
   *
 | 
						|
   * @param value the value to search for
 | 
						|
   * @return <code>true</code> if the map contains the value
 | 
						|
   * @throws ClassCastException if the type of the value is not a valid type
 | 
						|
   *         for this map.
 | 
						|
   * @throws NullPointerException if the value is null and the map doesn't
 | 
						|
   *         support null values.
 | 
						|
   */
 | 
						|
    public boolean containsValue(Object value)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.containsValue(value);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // This is one of the ickiest cases of nesting I've ever seen. It just
 | 
						|
    // means "return a SynchronizedSet, except that the iterator() method
 | 
						|
    // returns an SynchronizedIterator whose next() method returns a
 | 
						|
    // synchronized wrapper around its normal return value".
 | 
						|
    public Set<Map.Entry<K, V>> entrySet()
 | 
						|
    {
 | 
						|
      // Define this here to spare some nesting.
 | 
						|
      class SynchronizedMapEntry<K, V> implements Map.Entry<K, V>
 | 
						|
      {
 | 
						|
        final Map.Entry<K, V> e;
 | 
						|
        SynchronizedMapEntry(Map.Entry<K, V> o)
 | 
						|
        {
 | 
						|
          e = o;
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns <code>true</code> if the object, o, implements <code>Map.Entry</code>
 | 
						|
         * with the same key and value as the underlying entry.  A lock is
 | 
						|
         * obtained on the mutex before the comparison takes place.
 | 
						|
         *
 | 
						|
         * @param o The object to compare with this entry.
 | 
						|
         * @return <code>true</code> if o is equivalent to the underlying map entry.
 | 
						|
         */
 | 
						|
        public boolean equals(Object o)
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.equals(o);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns the key used in the underlying map entry.  A lock is obtained
 | 
						|
         * on the mutex before the key is retrieved.
 | 
						|
         *
 | 
						|
         * @return The key of the underlying map entry.
 | 
						|
         */
 | 
						|
        public K getKey()
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.getKey();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns the value used in the underlying map entry.  A lock is obtained
 | 
						|
         * on the mutex before the value is retrieved.
 | 
						|
         *
 | 
						|
         * @return The value of the underlying map entry.
 | 
						|
         */
 | 
						|
        public V getValue()
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.getValue();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Computes the hash code for the underlying map entry.
 | 
						|
         * This computation is described in the documentation for the
 | 
						|
         * <code>Map</code> interface.  A lock is obtained on the mutex
 | 
						|
         * before the underlying map is accessed.
 | 
						|
         *
 | 
						|
         * @return The hash code of the underlying map entry.
 | 
						|
         * @see Map#hashCode()
 | 
						|
         */
 | 
						|
        public int hashCode()
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.hashCode();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Replaces the value in the underlying map entry with the specified
 | 
						|
         * object (optional operation).  A lock is obtained on the mutex
 | 
						|
         * before the map is altered.  The map entry, in turn, will alter
 | 
						|
         * the underlying map object.  The operation is undefined if the
 | 
						|
         * <code>remove()</code> method of the iterator has been called
 | 
						|
         * beforehand.
 | 
						|
         *
 | 
						|
         * @param value the new value to store
 | 
						|
         * @return the old value
 | 
						|
         * @throws UnsupportedOperationException if the operation is not supported.
 | 
						|
         * @throws ClassCastException if the value is of the wrong type.
 | 
						|
         * @throws IllegalArgumentException if something about the value
 | 
						|
         *         prevents it from existing in this map.
 | 
						|
         * @throws NullPointerException if the map forbids null values.
 | 
						|
         */
 | 
						|
        public V setValue(V value)
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.setValue(value);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns a textual representation of the underlying map entry.
 | 
						|
         * A lock is obtained on the mutex before the entry is accessed.
 | 
						|
         *
 | 
						|
         * @return The contents of the map entry in <code>String</code> form.
 | 
						|
         */
 | 
						|
        public String toString()
 | 
						|
        {
 | 
						|
          synchronized (mutex)
 | 
						|
            {
 | 
						|
              return e.toString();
 | 
						|
            }
 | 
						|
        }
 | 
						|
      } // class SynchronizedMapEntry
 | 
						|
 | 
						|
      // Now the actual code.
 | 
						|
      if (entries == null)
 | 
						|
        synchronized (mutex)
 | 
						|
          {
 | 
						|
            entries = new SynchronizedSet<Map.Entry<K, V>>(mutex, m.entrySet())
 | 
						|
            {
 | 
						|
              /**
 | 
						|
               * Returns an iterator over the set.  The iterator has no specific order,
 | 
						|
               * unless further specified.  A lock is obtained on the set's mutex
 | 
						|
               * before the iterator is created.  The created iterator is also
 | 
						|
               * thread-safe.
 | 
						|
               *
 | 
						|
               * @return A synchronized set iterator.
 | 
						|
               */
 | 
						|
              public Iterator<Map.Entry<K, V>> iterator()
 | 
						|
              {
 | 
						|
                synchronized (super.mutex)
 | 
						|
                  {
 | 
						|
                    return new SynchronizedIterator<Map.Entry<K, V>>(super.mutex,
 | 
						|
                                                                     c.iterator())
 | 
						|
                    {
 | 
						|
                      /**
 | 
						|
                       * Retrieves the next map entry from the iterator.
 | 
						|
                       * A lock is obtained on the iterator's mutex before
 | 
						|
                       * the entry is created.  The new map entry is enclosed in
 | 
						|
                       * a thread-safe wrapper.
 | 
						|
                       *
 | 
						|
                       * @return A synchronized map entry.
 | 
						|
                       */
 | 
						|
                      public Map.Entry<K, V> next()
 | 
						|
                      {
 | 
						|
                        synchronized (super.mutex)
 | 
						|
                          {
 | 
						|
                            return new SynchronizedMapEntry<K, V>(super.next());
 | 
						|
                          }
 | 
						|
                      }
 | 
						|
                    };
 | 
						|
                  }
 | 
						|
              }
 | 
						|
            };
 | 
						|
          }
 | 
						|
      return entries;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is also an instance
 | 
						|
     * of <code>Map</code> and contains an equivalent
 | 
						|
     * entry set to that of the underlying map.  A lock
 | 
						|
     * is obtained on the mutex before the objects are
 | 
						|
     * compared.
 | 
						|
     *
 | 
						|
     * @param o The object to compare.
 | 
						|
     * @return <code>true</code> if o and the underlying map are equivalent.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.equals(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the value associated with the given key, or null
 | 
						|
     * if no such mapping exists.  An ambiguity exists with maps
 | 
						|
     * that accept null values as a return value of null could
 | 
						|
     * be due to a non-existent mapping or simply a null value
 | 
						|
     * for that key.  To resolve this, <code>containsKey</code>
 | 
						|
     * should be used.  A lock is obtained on the mutex before
 | 
						|
     * the value is retrieved from the underlying map.
 | 
						|
     *
 | 
						|
     * @param key The key of the required mapping.
 | 
						|
     * @return The value associated with the given key, or
 | 
						|
     *         null if no such mapping exists.
 | 
						|
     * @throws ClassCastException if the key is an inappropriate type.
 | 
						|
     * @throws NullPointerException if this map does not accept null keys.
 | 
						|
     */
 | 
						|
    public V get(Object key)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.get(key);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Calculates the hash code of the underlying map as the
 | 
						|
     * sum of the hash codes of all entries.  A lock is obtained
 | 
						|
     * on the mutex before the hash code is computed.
 | 
						|
     *
 | 
						|
     * @return The hash code of the underlying map.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.hashCode();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains no entries.
 | 
						|
     * A lock is obtained on the mutex before the map is examined.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if the map is empty.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.isEmpty();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a thread-safe set view of the keys in the underlying map.  The
 | 
						|
     * set is backed by the map, so that changes in one show up in the other.
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  If the set supports removal, these methods remove the
 | 
						|
     * underlying mapping from the map: <code>Iterator.remove</code>,
 | 
						|
     * <code>Set.remove</code>, <code>removeAll</code>, <code>retainAll</code>,
 | 
						|
     * and <code>clear</code>.  Element addition, via <code>add</code> or
 | 
						|
     * <code>addAll</code>, is not supported via this set.  A lock is obtained
 | 
						|
     * on the mutex before the set is created.
 | 
						|
     *
 | 
						|
     * @return A synchronized set containing the keys of the underlying map.
 | 
						|
     */
 | 
						|
    public Set<K> keySet()
 | 
						|
    {
 | 
						|
      if (keys == null)
 | 
						|
        synchronized (mutex)
 | 
						|
          {
 | 
						|
            keys = new SynchronizedSet<K>(mutex, m.keySet());
 | 
						|
          }
 | 
						|
      return keys;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Associates the given key to the given value (optional operation). If the
 | 
						|
     * underlying map already contains the key, its value is replaced. Be aware
 | 
						|
     * that in a map that permits <code>null</code> values, a null return does not
 | 
						|
     * always imply that the mapping was created.  A lock is obtained on the mutex
 | 
						|
     * before the modification is made.
 | 
						|
     *
 | 
						|
     * @param key the key to map.
 | 
						|
     * @param value the value to be mapped.
 | 
						|
     * @return the previous value of the key, or null if there was no mapping
 | 
						|
     * @throws UnsupportedOperationException if the operation is not supported
 | 
						|
     * @throws ClassCastException if the key or value is of the wrong type
 | 
						|
     * @throws IllegalArgumentException if something about this key or value
 | 
						|
     *         prevents it from existing in this map
 | 
						|
     * @throws NullPointerException if either the key or the value is null,
 | 
						|
     *         and the map forbids null keys or values
 | 
						|
     * @see #containsKey(Object)
 | 
						|
     */
 | 
						|
    public V put(K key, V value)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.put(key, value);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copies all entries of the given map to the underlying one (optional
 | 
						|
     * operation). If the map already contains a key, its value is replaced.
 | 
						|
     * A lock is obtained on the mutex before the operation proceeds.
 | 
						|
     *
 | 
						|
     * @param map the mapping to load into this map
 | 
						|
     * @throws UnsupportedOperationException if the operation is not supported
 | 
						|
     * @throws ClassCastException if a key or value is of the wrong type
 | 
						|
     * @throws IllegalArgumentException if something about a key or value
 | 
						|
     *         prevents it from existing in this map
 | 
						|
     * @throws NullPointerException if the map forbids null keys or values, or
 | 
						|
     *         if <code>m</code> is null.
 | 
						|
     * @see #put(Object, Object)
 | 
						|
     */
 | 
						|
    public void putAll(Map<? extends K, ? extends V> map)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          m.putAll(map);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the mapping for the key, o, if present (optional operation). If
 | 
						|
     * the key is not present, this returns null. Note that maps which permit
 | 
						|
     * null values may also return null if the key was removed.  A prior
 | 
						|
     * <code>containsKey()</code> check is required to avoid this ambiguity.
 | 
						|
     * Before the mapping is removed, a lock is obtained on the mutex.
 | 
						|
     *
 | 
						|
     * @param o the key to remove
 | 
						|
     * @return the value the key mapped to, or null if not present
 | 
						|
     * @throws UnsupportedOperationException if deletion is unsupported
 | 
						|
     * @throws NullPointerException if the key is null and this map doesn't
 | 
						|
     *         support null keys.
 | 
						|
     * @throws ClassCastException if the type of the key is not a valid type
 | 
						|
     *         for this map.
 | 
						|
     */
 | 
						|
    public V remove(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.remove(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the size of the underlying map.  A lock
 | 
						|
     * is obtained on the mutex before access takes place.
 | 
						|
     * Maps with a size greater than <code>Integer.MAX_VALUE</code>
 | 
						|
     * return <code>Integer.MAX_VALUE</code> instead.
 | 
						|
     *
 | 
						|
     * @return The size of the underlying map.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.size();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a textual representation of the underlying
 | 
						|
     * map.  A lock is obtained on the mutex before the map
 | 
						|
     * is accessed.
 | 
						|
     *
 | 
						|
     * @return The map in <code>String</code> form.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return m.toString();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a synchronized collection view of the values in the underlying
 | 
						|
     * map.  The collection is backed by the map, so that changes in one show up in
 | 
						|
     * the other.  Modifications made while an iterator is in progress cause
 | 
						|
     * undefined behavior.  If the collection supports removal, these methods
 | 
						|
     * remove the underlying mapping from the map: <code>Iterator.remove</code>,
 | 
						|
     * <code>Collection.remove</code>, <code>removeAll</code>,
 | 
						|
     * <code>retainAll</code>, and <code>clear</code>. Element addition, via
 | 
						|
     * <code>add</code> or <code>addAll</code>, is not supported via this
 | 
						|
     * collection.  A lock is obtained on the mutex before the collection
 | 
						|
     * is created.
 | 
						|
     *
 | 
						|
     * @return the collection of all values in the underlying map.
 | 
						|
     */
 | 
						|
    public Collection<V> values()
 | 
						|
    {
 | 
						|
      if (values == null)
 | 
						|
        synchronized (mutex)
 | 
						|
          {
 | 
						|
            values = new SynchronizedCollection<V>(mutex, m.values());
 | 
						|
          }
 | 
						|
      return values;
 | 
						|
    }
 | 
						|
  } // class SynchronizedMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) set wrapper backed by the given
 | 
						|
   * set. Notice that element access through the iterator is thread-safe, but
 | 
						|
   * if the set can be structurally modified (adding or removing elements)
 | 
						|
   * then you should synchronize around the iteration to avoid
 | 
						|
   * non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * Set s = Collections.synchronizedSet(new Set(...));
 | 
						|
   * ...
 | 
						|
   * synchronized (s)
 | 
						|
   *   {
 | 
						|
   *     Iterator i = s.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * The returned Set implements Serializable, but can only be serialized if
 | 
						|
   * the set it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param s the set to wrap
 | 
						|
   * @return a synchronized view of the set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Set<T> synchronizedSet(Set<T> s)
 | 
						|
  {
 | 
						|
    return new SynchronizedSet<T>(s);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedSet(Set)}. This class
 | 
						|
   * name is required for compatibility with Sun's JDK serializability.
 | 
						|
   * Package visible, so that sets such as Hashtable.keySet()
 | 
						|
   * can specify which object to synchronize on.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  static class SynchronizedSet<T> extends SynchronizedCollection<T>
 | 
						|
    implements Set<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 487447009682186044L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     * @param s the set to wrap
 | 
						|
     * @throws NullPointerException if s is null
 | 
						|
     */
 | 
						|
    SynchronizedSet(Set<T> s)
 | 
						|
    {
 | 
						|
      super(s);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the set.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param s the set
 | 
						|
     */
 | 
						|
    SynchronizedSet(Object sync, Set<T> s)
 | 
						|
    {
 | 
						|
      super(sync, s);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is a <code>Set</code>
 | 
						|
     * of the same size as the underlying set, and contains
 | 
						|
     * each element, e, which occurs in the underlying set.
 | 
						|
     * A lock is obtained on the mutex before the comparison
 | 
						|
     * takes place.
 | 
						|
     *
 | 
						|
     * @param o The object to compare against.
 | 
						|
     * @return <code>true</code> if o is an equivalent set.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.equals(o);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code for the underlying set as the
 | 
						|
     * sum of the hash code of all elements within the set.
 | 
						|
     * A lock is obtained on the mutex before the computation
 | 
						|
     * occurs.
 | 
						|
     *
 | 
						|
     * @return The hash code for the underlying set.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return c.hashCode();
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) sorted map wrapper backed by the
 | 
						|
   * given map. Notice that element access through the collection views,
 | 
						|
   * subviews, and their iterators are thread-safe, but if the map can be
 | 
						|
   * structurally modified (adding or removing elements) then you should
 | 
						|
   * synchronize around the iteration to avoid non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
 | 
						|
   * ...
 | 
						|
   * Set s = m.keySet(); // safe outside a synchronized block
 | 
						|
   * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
 | 
						|
   * Set s2 = m2.keySet(); // safe outside a synchronized block
 | 
						|
   * synchronized (m) // synch on m, not m2, s or s2
 | 
						|
   *   {
 | 
						|
   *     Iterator i = s.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *     i = s2.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       bar(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * The returned SortedMap implements Serializable, but can only be
 | 
						|
   * serialized if the map it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param m the sorted map to wrap
 | 
						|
   * @return a synchronized view of the sorted map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m)
 | 
						|
  {
 | 
						|
    return new SynchronizedSortedMap<K, V>(m);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SynchronizedSortedMap<K, V>
 | 
						|
    extends SynchronizedMap<K, V>
 | 
						|
    implements SortedMap<K, V>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -8798146769416483793L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     * @serial the wrapped map
 | 
						|
     */
 | 
						|
    private final SortedMap<K, V> sm;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     * @param sm the map to wrap
 | 
						|
     * @throws NullPointerException if sm is null
 | 
						|
     */
 | 
						|
    SynchronizedSortedMap(SortedMap<K, V> sm)
 | 
						|
    {
 | 
						|
      super(sm);
 | 
						|
      this.sm = sm;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the map.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param sm the map
 | 
						|
     */
 | 
						|
    SynchronizedSortedMap(Object sync, SortedMap<K, V> sm)
 | 
						|
    {
 | 
						|
      super(sync, sm);
 | 
						|
      this.sm = sm;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying map, or null if
 | 
						|
     * it is the keys' natural ordering.  A lock is obtained on the mutex
 | 
						|
     * before the comparator is retrieved.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator.
 | 
						|
     */
 | 
						|
    public Comparator<? super K> comparator()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return sm.comparator();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first, lowest sorted, key from the underlying map.
 | 
						|
     * A lock is obtained on the mutex before the map is accessed.
 | 
						|
     *
 | 
						|
     * @return the first key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K firstKey()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return sm.firstKey();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a submap containing the keys from the first
 | 
						|
     * key (as returned by <code>firstKey()</code>) to
 | 
						|
     * the key before that specified.  The submap supports all
 | 
						|
     * operations supported by the underlying map and all actions
 | 
						|
     * taking place on the submap are also reflected in the underlying
 | 
						|
     * map.  A lock is obtained on the mutex prior to submap creation.
 | 
						|
     * This operation is equivalent to <code>subMap(firstKey(), toKey)</code>.
 | 
						|
     * The submap retains the thread-safe status of this map.
 | 
						|
     *
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return a submap from <code>firstKey()</code> to the
 | 
						|
     *         the key preceding toKey.
 | 
						|
     * @throws ClassCastException if toKey is not comparable to the underlying
 | 
						|
     *         map's contents.
 | 
						|
     * @throws IllegalArgumentException if toKey is outside the map's range.
 | 
						|
     * @throws NullPointerException if toKey is null. but the map does not allow
 | 
						|
     *         null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> headMap(K toKey)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedMap<K, V>(mutex, sm.headMap(toKey));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last, highest sorted, key from the underlying map.
 | 
						|
     * A lock is obtained on the mutex before the map is accessed.
 | 
						|
     *
 | 
						|
     * @return the last key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K lastKey()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return sm.lastKey();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a submap containing the keys from fromKey to
 | 
						|
     * the key before toKey.  The submap supports all
 | 
						|
     * operations supported by the underlying map and all actions
 | 
						|
     * taking place on the submap are also reflected in the underlying
 | 
						|
     * map.  A lock is obtained on the mutex prior to submap creation.
 | 
						|
     * The submap retains the thread-safe status of this map.
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap.
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return a submap from fromKey to the key preceding toKey.
 | 
						|
     * @throws ClassCastException if fromKey or toKey is not comparable
 | 
						|
     *         to the underlying map's contents.
 | 
						|
     * @throws IllegalArgumentException if fromKey or toKey is outside the map's
 | 
						|
     *         range.
 | 
						|
     * @throws NullPointerException if fromKey or toKey is null. but the map does
 | 
						|
     *         not allow  null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> subMap(K fromKey, K toKey)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedMap<K, V>(mutex,
 | 
						|
                                                 sm.subMap(fromKey, toKey));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a submap containing all the keys from fromKey onwards.
 | 
						|
     * The submap supports all operations supported by the underlying
 | 
						|
     * map and all actions taking place on the submap are also reflected
 | 
						|
     * in the underlying map.  A lock is obtained on the mutex prior to
 | 
						|
     * submap creation.  The submap retains the thread-safe status of
 | 
						|
     * this map.
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap.
 | 
						|
     * @return a submap from fromKey to <code>lastKey()</code>.
 | 
						|
     * @throws ClassCastException if fromKey is not comparable to the underlying
 | 
						|
     *         map's contents.
 | 
						|
     * @throws IllegalArgumentException if fromKey is outside the map's range.
 | 
						|
     * @throws NullPointerException if fromKey is null. but the map does not allow
 | 
						|
     *         null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> tailMap(K fromKey)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedMap<K, V>(mutex, sm.tailMap(fromKey));
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedSortedMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a synchronized (thread-safe) sorted set wrapper backed by the
 | 
						|
   * given set. Notice that element access through the iterator and through
 | 
						|
   * subviews are thread-safe, but if the set can be structurally modified
 | 
						|
   * (adding or removing elements) then you should synchronize around the
 | 
						|
   * iteration to avoid non-deterministic behavior:<br>
 | 
						|
   * <pre>
 | 
						|
   * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
 | 
						|
   * ...
 | 
						|
   * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
 | 
						|
   * synchronized (s) // synch on s, not s2
 | 
						|
   *   {
 | 
						|
   *     Iterator i = s2.iterator();
 | 
						|
   *     while (i.hasNext())
 | 
						|
   *       foo(i.next());
 | 
						|
   *   }
 | 
						|
   * </pre><p>
 | 
						|
   *
 | 
						|
   * The returned SortedSet implements Serializable, but can only be
 | 
						|
   * serialized if the set it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param s the sorted set to wrap
 | 
						|
   * @return a synchronized view of the sorted set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
 | 
						|
  {
 | 
						|
    return new SynchronizedSortedSet<T>(s);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class SynchronizedSortedSet<T>
 | 
						|
    extends SynchronizedSet<T>
 | 
						|
    implements SortedSet<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 8695801310862127406L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped set; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     * @serial the wrapped set
 | 
						|
     */
 | 
						|
    private final SortedSet<T> ss;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     * @param ss the set to wrap
 | 
						|
     * @throws NullPointerException if ss is null
 | 
						|
     */
 | 
						|
    SynchronizedSortedSet(SortedSet<T> ss)
 | 
						|
    {
 | 
						|
      super(ss);
 | 
						|
      this.ss = ss;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called only by trusted code to specify the mutex as well as the set.
 | 
						|
     * @param sync the mutex
 | 
						|
     * @param ss the set
 | 
						|
     */
 | 
						|
    SynchronizedSortedSet(Object sync, SortedSet<T> ss)
 | 
						|
    {
 | 
						|
      super(sync, ss);
 | 
						|
      this.ss = ss;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying set, or null if
 | 
						|
     * it is the elements' natural ordering.  A lock is obtained on the mutex
 | 
						|
     * before the comparator is retrieved.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator.
 | 
						|
     */
 | 
						|
    public Comparator<? super T> comparator()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return ss.comparator();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first, lowest sorted, element from the underlying set.
 | 
						|
     * A lock is obtained on the mutex before the set is accessed.
 | 
						|
     *
 | 
						|
     * @return the first element.
 | 
						|
     * @throws NoSuchElementException if this set is empty.
 | 
						|
     */
 | 
						|
    public T first()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return ss.first();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a subset containing the element from the first
 | 
						|
     * element (as returned by <code>first()</code>) to
 | 
						|
     * the element before that specified.  The subset supports all
 | 
						|
     * operations supported by the underlying set and all actions
 | 
						|
     * taking place on the subset are also reflected in the underlying
 | 
						|
     * set.  A lock is obtained on the mutex prior to subset creation.
 | 
						|
     * This operation is equivalent to <code>subSet(first(), toElement)</code>.
 | 
						|
     * The subset retains the thread-safe status of this set.
 | 
						|
     *
 | 
						|
     * @param toElement the exclusive upper range of the subset.
 | 
						|
     * @return a subset from <code>first()</code> to the
 | 
						|
     *         the element preceding toElement.
 | 
						|
     * @throws ClassCastException if toElement is not comparable to the underlying
 | 
						|
     *         set's contents.
 | 
						|
     * @throws IllegalArgumentException if toElement is outside the set's range.
 | 
						|
     * @throws NullPointerException if toElement is null. but the set does not allow
 | 
						|
     *         null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> headSet(T toElement)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedSet<T>(mutex, ss.headSet(toElement));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last, highest sorted, element from the underlying set.
 | 
						|
     * A lock is obtained on the mutex before the set is accessed.
 | 
						|
     *
 | 
						|
     * @return the last element.
 | 
						|
     * @throws NoSuchElementException if this set is empty.
 | 
						|
     */
 | 
						|
    public T last()
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return ss.last();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a subset containing the elements from fromElement to
 | 
						|
     * the element before toElement.  The subset supports all
 | 
						|
     * operations supported by the underlying set and all actions
 | 
						|
     * taking place on the subset are also reflected in the underlying
 | 
						|
     * set.  A lock is obtained on the mutex prior to subset creation.
 | 
						|
     * The subset retains the thread-safe status of this set.
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset.
 | 
						|
     * @param toElement the exclusive upper range of the subset.
 | 
						|
     * @return a subset from fromElement to the element preceding toElement.
 | 
						|
     * @throws ClassCastException if fromElement or toElement is not comparable
 | 
						|
     *         to the underlying set's contents.
 | 
						|
     * @throws IllegalArgumentException if fromElement or toElement is outside the set's
 | 
						|
     *         range.
 | 
						|
     * @throws NullPointerException if fromElement or toElement is null. but the set does
 | 
						|
     *         not allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> subSet(T fromElement, T toElement)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedSet<T>(mutex,
 | 
						|
                                              ss.subSet(fromElement,
 | 
						|
                                                        toElement));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a subset containing all the elements from fromElement onwards.
 | 
						|
     * The subset supports all operations supported by the underlying
 | 
						|
     * set and all actions taking place on the subset are also reflected
 | 
						|
     * in the underlying set.  A lock is obtained on the mutex prior to
 | 
						|
     * subset creation.  The subset retains the thread-safe status of
 | 
						|
     * this set.
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset.
 | 
						|
     * @return a subset from fromElement to <code>last()</code>.
 | 
						|
     * @throws ClassCastException if fromElement is not comparable to the underlying
 | 
						|
     *         set's contents.
 | 
						|
     * @throws IllegalArgumentException if fromElement is outside the set's range.
 | 
						|
     * @throws NullPointerException if fromElement is null. but the set does not allow
 | 
						|
     *         null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> tailSet(T fromElement)
 | 
						|
    {
 | 
						|
      synchronized (mutex)
 | 
						|
        {
 | 
						|
          return new SynchronizedSortedSet<T>(mutex, ss.tailSet(fromElement));
 | 
						|
        }
 | 
						|
    }
 | 
						|
  } // class SynchronizedSortedSet
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given collection. This allows
 | 
						|
   * "read-only" access, although changes in the backing collection show up
 | 
						|
   * in this view. Attempts to modify the collection directly or via iterators
 | 
						|
   * will fail with {@link UnsupportedOperationException}.  Although this view
 | 
						|
   * prevents changes to the structure of the collection and its elements, the values
 | 
						|
   * referenced by the objects in the collection can still be modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * Since the collection might be a List or a Set, and those have incompatible
 | 
						|
   * equals and hashCode requirements, this relies on Object's implementation
 | 
						|
   * rather than passing those calls on to the wrapped collection. The returned
 | 
						|
   * Collection implements Serializable, but can only be serialized if
 | 
						|
   * the collection it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param c the collection to wrap
 | 
						|
   * @return a read-only view of the collection
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
 | 
						|
  {
 | 
						|
    return new UnmodifiableCollection<T>(c);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableCollection(Collection)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableCollection<T>
 | 
						|
    implements Collection<T>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1820017752578914078L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped collection. Package visible for use by subclasses.
 | 
						|
     * @serial the real collection
 | 
						|
     */
 | 
						|
    final Collection<? extends T> c;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given collection.
 | 
						|
     * @param c the collection to wrap
 | 
						|
     * @throws NullPointerException if c is null
 | 
						|
     */
 | 
						|
    UnmodifiableCollection(Collection<? extends T> c)
 | 
						|
    {
 | 
						|
      this.c = c;
 | 
						|
      if (c == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of elements to the underlying collection.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param o the object to add.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result of this action.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection does not
 | 
						|
     *         support the add operation.
 | 
						|
     */
 | 
						|
    public boolean add(T o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of a collection of elements to the underlying
 | 
						|
     * collection.  This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param c the collection to add.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result of this action.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection does not
 | 
						|
     *         support the <code>addAll</code> operation.
 | 
						|
     */
 | 
						|
    public boolean addAll(Collection<? extends T> c)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the clearing of the underlying collection.  This method never
 | 
						|
     * returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection does
 | 
						|
     *         not support the <code>clear()</code> operation.
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test whether the underlying collection contains a given object as one of its
 | 
						|
     * elements.
 | 
						|
     *
 | 
						|
     * @param o the element to look for.
 | 
						|
     * @return <code>true</code> if the underlying collection contains at least
 | 
						|
     *         one element e such that
 | 
						|
     *         <code>o == null ? e == null : o.equals(e)</code>.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid type for the
 | 
						|
     *         underlying collection.
 | 
						|
     * @throws NullPointerException if o is null and the underlying collection
 | 
						|
     *         doesn't support null values.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return c.contains(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test whether the underlying collection contains every element in a given
 | 
						|
     * collection.
 | 
						|
     *
 | 
						|
     * @param c1 the collection to test for.
 | 
						|
     * @return <code>true</code> if for every element o in c, contains(o) would
 | 
						|
     *         return <code>true</code>.
 | 
						|
     * @throws ClassCastException if the type of any element in c is not a valid
 | 
						|
     *   type for the underlying collection.
 | 
						|
     * @throws NullPointerException if some element of c is null and the underlying
 | 
						|
     *   collection does not support null values.
 | 
						|
     * @throws NullPointerException if c itself is null.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> c1)
 | 
						|
    {
 | 
						|
      return c.containsAll(c1);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether the underlying collection is empty, that is,
 | 
						|
     * if size() == 0.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if this collection contains no elements.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return c.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain an Iterator over the underlying collection, which maintains
 | 
						|
     * its unmodifiable nature.
 | 
						|
     *
 | 
						|
     * @return an UnmodifiableIterator over the elements of the underlying
 | 
						|
     *         collection, in any order.
 | 
						|
     */
 | 
						|
    public Iterator<T> iterator()
 | 
						|
    {
 | 
						|
      return new UnmodifiableIterator<T>(c.iterator());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of an object from the underlying collection.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param o The object to remove.
 | 
						|
     * @return <code>true</code> if the object was removed (i.e. the underlying
 | 
						|
     *         collection returned 1 or more instances of o).
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection
 | 
						|
     *         does not support the <code>remove()</code> operation.
 | 
						|
     */
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of a collection of objects from the underlying
 | 
						|
     * collection.  This method never returns, throwing an exception
 | 
						|
     * instead.
 | 
						|
     *
 | 
						|
     * @param c The collection of objects to remove.
 | 
						|
     * @return <code>true</code> if the collection was modified.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection
 | 
						|
     *         does not support the <code>removeAll()</code> operation.
 | 
						|
     */
 | 
						|
    public boolean removeAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of all elements from the underlying collection,
 | 
						|
     * except those in the supplied collection.  This method never returns,
 | 
						|
     * throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param c The collection of objects to retain.
 | 
						|
     * @return <code>true</code> if the collection was modified.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection
 | 
						|
     *         does not support the <code>retainAll()</code> operation.
 | 
						|
     */
 | 
						|
    public boolean retainAll(Collection<?> c)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the number of elements in the underlying collection.
 | 
						|
     *
 | 
						|
     * @return the number of elements in the collection.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return c.size();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copy the current contents of the underlying collection into an array.
 | 
						|
     *
 | 
						|
     * @return an array of type Object[] with a length equal to the size of the
 | 
						|
     *         underlying collection and containing the elements currently in
 | 
						|
     *         the underlying collection, in any order.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return c.toArray();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copy the current contents of the underlying collection into an array.  If
 | 
						|
     * the array passed as an argument has length less than the size of the
 | 
						|
     * underlying collection, an array of the same run-time type as a, with a length
 | 
						|
     * equal to the size of the underlying collection, is allocated using reflection.
 | 
						|
     * Otherwise, a itself is used.  The elements of the underlying collection are
 | 
						|
     * copied into it, and if there is space in the array, the following element is
 | 
						|
     * set to null. The resultant array is returned.
 | 
						|
     * Note: The fact that the following element is set to null is only useful
 | 
						|
     * if it is known that this collection does not contain any null elements.
 | 
						|
     *
 | 
						|
     * @param a the array to copy this collection into.
 | 
						|
     * @return an array containing the elements currently in the underlying
 | 
						|
     *         collection, in any order.
 | 
						|
     * @throws ArrayStoreException if the type of any element of the
 | 
						|
     *         collection is not a subtype of the element type of a.
 | 
						|
     */
 | 
						|
    public <S> S[] toArray(S[] a)
 | 
						|
    {
 | 
						|
      return c.toArray(a);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * A textual representation of the unmodifiable collection.
 | 
						|
     *
 | 
						|
     * @return The unmodifiable collection in the form of a <code>String</code>.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return c.toString();
 | 
						|
    }
 | 
						|
  } // class UnmodifiableCollection
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of the various iterator methods in the
 | 
						|
   * unmodifiable classes.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableIterator<T> implements Iterator<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The wrapped iterator.
 | 
						|
     */
 | 
						|
    private final Iterator<? extends T> i;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper.
 | 
						|
     * @param i the wrapped iterator
 | 
						|
     */
 | 
						|
    UnmodifiableIterator(Iterator<? extends T> i)
 | 
						|
    {
 | 
						|
      this.i = i;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains the next element in the underlying collection.
 | 
						|
     *
 | 
						|
     * @return the next element in the collection.
 | 
						|
     * @throws NoSuchElementException if there are no more elements.
 | 
						|
     */
 | 
						|
    public T next()
 | 
						|
    {
 | 
						|
      return i.next();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether there are still elements to be retrieved from the
 | 
						|
     * underlying collection by <code>next()</code>.  When this method
 | 
						|
     * returns <code>true</code>, an exception will not be thrown on calling
 | 
						|
     * <code>next()</code>.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if there is at least one more element in the underlying
 | 
						|
     *         collection.
 | 
						|
     */
 | 
						|
    public boolean hasNext()
 | 
						|
    {
 | 
						|
      return i.hasNext();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of elements from the underlying collection by the
 | 
						|
     * iterator.
 | 
						|
     *
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable collection
 | 
						|
     *         does not support the removal of elements by its iterator.
 | 
						|
     */
 | 
						|
    public void remove()
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
  } // class UnmodifiableIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given list. This allows
 | 
						|
   * "read-only" access, although changes in the backing list show up
 | 
						|
   * in this view. Attempts to modify the list directly, via iterators, or
 | 
						|
   * via sublists, will fail with {@link UnsupportedOperationException}.
 | 
						|
   * Although this view prevents changes to the structure of the list and
 | 
						|
   * its elements, the values referenced by the objects in the list can
 | 
						|
   * still be modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * The returned List implements Serializable, but can only be serialized if
 | 
						|
   * the list it wraps is likewise Serializable. In addition, if the wrapped
 | 
						|
   * list implements RandomAccess, this does too.
 | 
						|
   *
 | 
						|
   * @param l the list to wrap
 | 
						|
   * @return a read-only view of the list
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   */
 | 
						|
  public static <T> List<T> unmodifiableList(List<? extends T> l)
 | 
						|
  {
 | 
						|
    if (l instanceof RandomAccess)
 | 
						|
      return new UnmodifiableRandomAccessList<T>(l);
 | 
						|
    return new UnmodifiableList<T>(l);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableList(List)} for sequential
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableList<T> extends UnmodifiableCollection<T>
 | 
						|
    implements List<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -283967356065247728L;
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped list; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting. Package visible for use by subclass.
 | 
						|
     * @serial the wrapped list
 | 
						|
     */
 | 
						|
    final List<T> list;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    UnmodifiableList(List<? extends T> l)
 | 
						|
    {
 | 
						|
      super(l);
 | 
						|
      list = (List<T>) l;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of an element to the underlying
 | 
						|
     * list at a specific index.  This method never returns,
 | 
						|
     * throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param index The index at which to place the new element.
 | 
						|
     * @param o the object to add.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         list doesn't support the <code>add()</code> operation.
 | 
						|
     */
 | 
						|
    public void add(int index, T o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of a collection of elements to the
 | 
						|
     * underlying list at a specific index.  This method never
 | 
						|
     * returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param index The index at which to place the new element.
 | 
						|
     * @param c the collections of objects to add.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         list doesn't support the <code>addAll()</code> operation.
 | 
						|
     */
 | 
						|
    public boolean addAll(int index, Collection<? extends T> c)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is an instance of
 | 
						|
     * <code>List</code> with the same size and elements
 | 
						|
     * as the underlying list.
 | 
						|
     *
 | 
						|
     * @param o The object to compare.
 | 
						|
     * @return <code>true</code> if o is equivalent to the underlying list.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return list.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the element at a given index in the underlying list.
 | 
						|
     *
 | 
						|
     * @param index the index of the element to be returned
 | 
						|
     * @return the element at index index in this list
 | 
						|
     * @throws IndexOutOfBoundsException if index < 0 || index >= size()
 | 
						|
     */
 | 
						|
    public T get(int index)
 | 
						|
    {
 | 
						|
      return list.get(index);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code for the underlying list.
 | 
						|
     * The exact computation is described in the documentation
 | 
						|
     * of the <code>List</code> interface.
 | 
						|
     *
 | 
						|
     * @return The hash code of the underlying list.
 | 
						|
     * @see List#hashCode()
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return list.hashCode();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the first index at which a given object is to be found in the
 | 
						|
     * underlying list.
 | 
						|
     *
 | 
						|
     * @param o the object to search for
 | 
						|
     * @return the least integer n such that <code>o == null ? get(n) == null :
 | 
						|
     *         o.equals(get(n))</code>, or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for the underlying list.
 | 
						|
     * @throws NullPointerException if o is null and the underlying
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      return list.indexOf(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the last index at which a given object is to be found in the
 | 
						|
     * underlying list.
 | 
						|
     *
 | 
						|
     * @return the greatest integer n such that <code>o == null ? get(n) == null
 | 
						|
     *         : o.equals(get(n))</code>, or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for the underlying list.
 | 
						|
     * @throws NullPointerException if o is null and the underlying
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      return list.lastIndexOf(o);
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtains a list iterator over the underlying list, starting at the beginning
 | 
						|
   * and maintaining the unmodifiable nature of this list.
 | 
						|
   *
 | 
						|
   * @return a <code>UnmodifiableListIterator</code> over the elements of the
 | 
						|
   *         underlying list, in order, starting at the beginning.
 | 
						|
   */
 | 
						|
    public ListIterator<T> listIterator()
 | 
						|
    {
 | 
						|
      return new UnmodifiableListIterator<T>(list.listIterator());
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtains a list iterator over the underlying list, starting at the specified
 | 
						|
   * index and maintaining the unmodifiable nature of this list.  An initial call
 | 
						|
   * to <code>next()</code> will retrieve the element at the specified index,
 | 
						|
   * and an initial call to <code>previous()</code> will retrieve the element
 | 
						|
   * at index - 1.
 | 
						|
   *
 | 
						|
   *
 | 
						|
   * @param index the position, between 0 and size() inclusive, to begin the
 | 
						|
   *        iteration from.
 | 
						|
   * @return a <code>UnmodifiableListIterator</code> over the elements of the
 | 
						|
   *         underlying list, in order, starting at the specified index.
 | 
						|
   * @throws IndexOutOfBoundsException if index < 0 || index > size()
 | 
						|
   */
 | 
						|
    public ListIterator<T> listIterator(int index)
 | 
						|
    {
 | 
						|
      return new UnmodifiableListIterator<T>(list.listIterator(index));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of the element at the specified index.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param index The index of the element to remove.
 | 
						|
     * @return the removed element.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         list does not support the <code>remove()</code>
 | 
						|
     *         operation.
 | 
						|
     */
 | 
						|
    public T remove(int index)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the replacement of the element at the specified index.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param index The index of the element to replace.
 | 
						|
     * @param o The new object to place at the specified index.
 | 
						|
     * @return the replaced element.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         list does not support the <code>set()</code>
 | 
						|
     *         operation.
 | 
						|
     */
 | 
						|
    public T set(int index, T o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain a List view of a subsection of the underlying list, from
 | 
						|
     * fromIndex (inclusive) to toIndex (exclusive). If the two indices
 | 
						|
     * are equal, the sublist is empty. The returned list will be
 | 
						|
     * unmodifiable, like this list.  Changes to the elements of the
 | 
						|
     * returned list will be reflected in the underlying list. No structural
 | 
						|
     * modifications can take place in either list.
 | 
						|
     *
 | 
						|
     * @param fromIndex the index that the returned list should start from
 | 
						|
     *        (inclusive).
 | 
						|
     * @param toIndex the index that the returned list should go to (exclusive).
 | 
						|
     * @return a List backed by a subsection of the underlying list.
 | 
						|
     * @throws IndexOutOfBoundsException if fromIndex < 0
 | 
						|
     *         || toIndex > size() || fromIndex > toIndex.
 | 
						|
     */
 | 
						|
    public List<T> subList(int fromIndex, int toIndex)
 | 
						|
    {
 | 
						|
      return unmodifiableList(list.subList(fromIndex, toIndex));
 | 
						|
    }
 | 
						|
  } // class UnmodifiableList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableList(List)} for random-access
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class UnmodifiableRandomAccessList<T>
 | 
						|
    extends UnmodifiableList<T> implements RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -2542308836966382001L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    UnmodifiableRandomAccessList(List<? extends T> l)
 | 
						|
    {
 | 
						|
      super(l);
 | 
						|
    }
 | 
						|
  } // class UnmodifiableRandomAccessList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link UnmodifiableList#listIterator()}.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static final class UnmodifiableListIterator<T>
 | 
						|
    extends UnmodifiableIterator<T> implements ListIterator<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The wrapped iterator, stored both here and in the superclass to
 | 
						|
     * avoid excessive casting.
 | 
						|
     */
 | 
						|
    private final ListIterator<T> li;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper.
 | 
						|
     * @param li the wrapped iterator
 | 
						|
     */
 | 
						|
    UnmodifiableListIterator(ListIterator<T> li)
 | 
						|
    {
 | 
						|
      super(li);
 | 
						|
      this.li = li;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of an object to the list underlying this iterator.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param o The object to add.
 | 
						|
     * @throws UnsupportedOperationException as the iterator of an unmodifiable
 | 
						|
     *         list does not support the <code>add()</code> operation.
 | 
						|
     */
 | 
						|
    public void add(T o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether there are still elements to be retrieved from the
 | 
						|
     * underlying collection by <code>previous()</code>.  When this method
 | 
						|
     * returns <code>true</code>, an exception will not be thrown on calling
 | 
						|
     * <code>previous()</code>.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if there is at least one more element prior to the
 | 
						|
     *         current position in the underlying list.
 | 
						|
     */
 | 
						|
    public boolean hasPrevious()
 | 
						|
    {
 | 
						|
      return li.hasPrevious();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find the index of the element that would be returned by a call to next.
 | 
						|
     * If <code>hasNext()</code> returns <code>false</code>, this returns the list size.
 | 
						|
     *
 | 
						|
     * @return the index of the element that would be returned by
 | 
						|
     *         <code>next()</code>.
 | 
						|
     */
 | 
						|
    public int nextIndex()
 | 
						|
    {
 | 
						|
      return li.nextIndex();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains the previous element in the underlying list.
 | 
						|
     *
 | 
						|
     * @return the previous element in the list.
 | 
						|
     * @throws NoSuchElementException if there are no more prior elements.
 | 
						|
     */
 | 
						|
    public T previous()
 | 
						|
    {
 | 
						|
      return li.previous();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find the index of the element that would be returned by a call to
 | 
						|
     * previous. If <code>hasPrevious()</code> returns <code>false</code>,
 | 
						|
     * this returns -1.
 | 
						|
     *
 | 
						|
     * @return the index of the element that would be returned by
 | 
						|
     *         <code>previous()</code>.
 | 
						|
     */
 | 
						|
    public int previousIndex()
 | 
						|
    {
 | 
						|
      return li.previousIndex();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the replacement of an element in the list underlying this
 | 
						|
     * iterator.  This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param o The new object to replace the existing one.
 | 
						|
     * @throws UnsupportedOperationException as the iterator of an unmodifiable
 | 
						|
     *         list does not support the <code>set()</code> operation.
 | 
						|
     */
 | 
						|
    public void set(T o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
  } // class UnmodifiableListIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given map. This allows "read-only"
 | 
						|
   * access, although changes in the backing map show up in this view.
 | 
						|
   * Attempts to modify the map directly, or via collection views or their
 | 
						|
   * iterators will fail with {@link UnsupportedOperationException}.
 | 
						|
   * Although this view prevents changes to the structure of the map and its
 | 
						|
   * entries, the values referenced by the objects in the map can still be
 | 
						|
   * modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * The returned Map implements Serializable, but can only be serialized if
 | 
						|
   * the map it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param m the map to wrap
 | 
						|
   * @return a read-only view of the map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> Map<K, V> unmodifiableMap(Map<? extends K,
 | 
						|
                                                 ? extends V> m)
 | 
						|
  {
 | 
						|
    return new UnmodifiableMap<K, V>(m);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableMap(Map)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableMap<K, V> implements Map<K, V>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -1034234728574286014L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map.
 | 
						|
     * @serial the real map
 | 
						|
     */
 | 
						|
    private final Map<K, V> m;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the entry set.
 | 
						|
     */
 | 
						|
    private transient Set<Map.Entry<K, V>> entries;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the key set.
 | 
						|
     */
 | 
						|
    private transient Set<K> keys;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the value collection.
 | 
						|
     */
 | 
						|
    private transient Collection<V> values;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     * @param m the map to wrap
 | 
						|
     * @throws NullPointerException if m is null
 | 
						|
     */
 | 
						|
    UnmodifiableMap(Map<? extends K, ? extends V> m)
 | 
						|
    {
 | 
						|
      this.m = (Map<K,V>) m;
 | 
						|
      if (m == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the clearing of entries from the underlying map.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         map does not support the <code>clear()</code> operation.
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains a mapping for
 | 
						|
     * the given key.
 | 
						|
     *
 | 
						|
     * @param key the key to search for
 | 
						|
     * @return <code>true</code> if the map contains the key
 | 
						|
     * @throws ClassCastException if the key is of an inappropriate type
 | 
						|
     * @throws NullPointerException if key is <code>null</code> but the map
 | 
						|
     *         does not permit null keys
 | 
						|
     */
 | 
						|
    public boolean containsKey(Object key)
 | 
						|
    {
 | 
						|
      return m.containsKey(key);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains at least one mapping with
 | 
						|
     * the given value.  In other words, it returns <code>true</code> if a value v exists where
 | 
						|
     * <code>(value == null ? v == null : value.equals(v))</code>. This usually
 | 
						|
     * requires linear time.
 | 
						|
     *
 | 
						|
     * @param value the value to search for
 | 
						|
     * @return <code>true</code> if the map contains the value
 | 
						|
     * @throws ClassCastException if the type of the value is not a valid type
 | 
						|
     *         for this map.
 | 
						|
     * @throws NullPointerException if the value is null and the map doesn't
 | 
						|
     *         support null values.
 | 
						|
     */
 | 
						|
    public boolean containsValue(Object value)
 | 
						|
    {
 | 
						|
      return m.containsValue(value);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable set view of the entries in the underlying map.
 | 
						|
     * Each element in the set is a unmodifiable variant of <code>Map.Entry</code>.
 | 
						|
     * The set is backed by the map, so that changes in one show up in the other.
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  These modifications are again limited to the values of
 | 
						|
     * the objects.
 | 
						|
     *
 | 
						|
     * @return the unmodifiable set view of all mapping entries.
 | 
						|
     * @see Map.Entry
 | 
						|
     */
 | 
						|
    public Set<Map.Entry<K, V>> entrySet()
 | 
						|
    {
 | 
						|
      if (entries == null)
 | 
						|
        entries = new UnmodifiableEntrySet<K,V>(m.entrySet());
 | 
						|
      return entries;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The implementation of {@link UnmodifiableMap#entrySet()}. This class
 | 
						|
     * name is required for compatibility with Sun's JDK serializability.
 | 
						|
     *
 | 
						|
     * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
     */
 | 
						|
    private static final class UnmodifiableEntrySet<K,V>
 | 
						|
      extends UnmodifiableSet<Map.Entry<K,V>>
 | 
						|
      implements Serializable
 | 
						|
    {
 | 
						|
      // Unmodifiable implementation of Map.Entry used as return value for
 | 
						|
      // UnmodifiableEntrySet accessors (iterator, toArray, toArray(Object[]))
 | 
						|
      private static final class UnmodifiableMapEntry<K,V>
 | 
						|
          implements Map.Entry<K,V>
 | 
						|
      {
 | 
						|
        private final Map.Entry<K,V> e;
 | 
						|
 | 
						|
        private UnmodifiableMapEntry(Map.Entry<K,V> e)
 | 
						|
        {
 | 
						|
          super();
 | 
						|
          this.e = e;
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns <code>true</code> if the object, o, is also a map entry
 | 
						|
         * with an identical key and value.
 | 
						|
         *
 | 
						|
         * @param o the object to compare.
 | 
						|
         * @return <code>true</code> if o is an equivalent map entry.
 | 
						|
         */
 | 
						|
        public boolean equals(Object o)
 | 
						|
        {
 | 
						|
          return e.equals(o);
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns the key of this map entry.
 | 
						|
         *
 | 
						|
         * @return the key.
 | 
						|
         */
 | 
						|
        public K getKey()
 | 
						|
        {
 | 
						|
          return e.getKey();
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns the value of this map entry.
 | 
						|
         *
 | 
						|
         * @return the value.
 | 
						|
         */
 | 
						|
        public V getValue()
 | 
						|
        {
 | 
						|
          return e.getValue();
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Computes the hash code of this map entry. The computation is
 | 
						|
         * described in the <code>Map</code> interface documentation.
 | 
						|
         *
 | 
						|
         * @return the hash code of this entry.
 | 
						|
         * @see Map#hashCode()
 | 
						|
         */
 | 
						|
        public int hashCode()
 | 
						|
        {
 | 
						|
          return e.hashCode();
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Blocks the alteration of the value of this map entry. This method
 | 
						|
         * never returns, throwing an exception instead.
 | 
						|
         *
 | 
						|
         * @param value The new value.
 | 
						|
         * @throws UnsupportedOperationException as an unmodifiable map entry
 | 
						|
         *           does not support the <code>setValue()</code> operation.
 | 
						|
         */
 | 
						|
        public V setValue(V value)
 | 
						|
        {
 | 
						|
          throw new UnsupportedOperationException();
 | 
						|
        }
 | 
						|
 | 
						|
        /**
 | 
						|
         * Returns a textual representation of the map entry.
 | 
						|
         *
 | 
						|
         * @return The map entry as a <code>String</code>.
 | 
						|
         */
 | 
						|
        public String toString()
 | 
						|
        {
 | 
						|
          return e.toString();
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Compatible with JDK 1.4.
 | 
						|
       */
 | 
						|
      private static final long serialVersionUID = 7854390611657943733L;
 | 
						|
 | 
						|
      /**
 | 
						|
       * Wrap a given set.
 | 
						|
       * @param s the set to wrap
 | 
						|
       */
 | 
						|
      UnmodifiableEntrySet(Set<Map.Entry<K,V>> s)
 | 
						|
      {
 | 
						|
        super(s);
 | 
						|
      }
 | 
						|
 | 
						|
      // The iterator must return unmodifiable map entries.
 | 
						|
      public Iterator<Map.Entry<K,V>> iterator()
 | 
						|
      {
 | 
						|
        return new UnmodifiableIterator<Map.Entry<K,V>>(c.iterator())
 | 
						|
        {
 | 
						|
          /**
 | 
						|
           * Obtains the next element from the underlying set of
 | 
						|
           * map entries.
 | 
						|
           *
 | 
						|
           * @return the next element in the collection.
 | 
						|
           * @throws NoSuchElementException if there are no more elements.
 | 
						|
           */
 | 
						|
          public Map.Entry<K,V> next()
 | 
						|
          {
 | 
						|
            final Map.Entry<K,V> e = super.next();
 | 
						|
            return new UnmodifiableMapEntry<K,V>(e);
 | 
						|
          }
 | 
						|
        };
 | 
						|
      }
 | 
						|
 | 
						|
      // The array returned is an array of UnmodifiableMapEntry instead of
 | 
						|
      // Map.Entry
 | 
						|
      public Object[] toArray()
 | 
						|
      {
 | 
						|
        Object[] mapEntryResult = super.toArray();
 | 
						|
        UnmodifiableMapEntry<K,V> result[] = null;
 | 
						|
 | 
						|
        if (mapEntryResult != null)
 | 
						|
          {
 | 
						|
            result = (UnmodifiableMapEntry<K,V>[])
 | 
						|
              new UnmodifiableMapEntry[mapEntryResult.length];
 | 
						|
            for (int i = 0; i < mapEntryResult.length; ++i)
 | 
						|
              result[i] = new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>)mapEntryResult[i]);
 | 
						|
          }
 | 
						|
        return result;
 | 
						|
      }
 | 
						|
 | 
						|
      // The array returned is an array of UnmodifiableMapEntry instead of
 | 
						|
      // Map.Entry
 | 
						|
      public <S> S[] toArray(S[] array)
 | 
						|
      {
 | 
						|
        S[] result = super.toArray(array);
 | 
						|
 | 
						|
        if (result != null)
 | 
						|
          for (int i = 0; i < result.length; i++)
 | 
						|
            array[i] =
 | 
						|
              (S) new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>) result[i]);
 | 
						|
        return array;
 | 
						|
      }
 | 
						|
 | 
						|
 | 
						|
    } // class UnmodifiableEntrySet
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is also an instance
 | 
						|
     * of <code>Map</code> with an equal set of map entries.
 | 
						|
     *
 | 
						|
     * @param o The object to compare.
 | 
						|
     * @return <code>true</code> if o is an equivalent map.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return m.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the value associated with the supplied key or
 | 
						|
     * null if no such mapping exists.  An ambiguity can occur
 | 
						|
     * if null values are accepted by the underlying map.
 | 
						|
     * In this case, <code>containsKey()</code> can be used
 | 
						|
     * to separate the two possible cases of a null result.
 | 
						|
     *
 | 
						|
     * @param key The key to look up.
 | 
						|
     * @return the value associated with the key, or null if key not in map.
 | 
						|
     * @throws ClassCastException if the key is an inappropriate type.
 | 
						|
     * @throws NullPointerException if this map does not accept null keys.
 | 
						|
     * @see #containsKey(Object)
 | 
						|
     */
 | 
						|
    public V get(Object key)
 | 
						|
    {
 | 
						|
      return m.get(key);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of a new entry to the underlying map.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param key The new key.
 | 
						|
     * @param value The new value.
 | 
						|
     * @return the previous value of the key, or null if there was no mapping.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         map does not support the <code>put()</code> operation.
 | 
						|
     */
 | 
						|
    public V put(K key, V value)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code for the underlying map, as the sum
 | 
						|
     * of the hash codes of all entries.
 | 
						|
     *
 | 
						|
     * @return The hash code of the underlying map.
 | 
						|
     * @see Map.Entry#hashCode()
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return m.hashCode();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains no entries.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if the map is empty.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return m.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable set view of the keys in the underlying map.
 | 
						|
     * The set is backed by the map, so that changes in one show up in the other.
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  These modifications are again limited to the values of
 | 
						|
     * the keys.
 | 
						|
     *
 | 
						|
     * @return the set view of all keys.
 | 
						|
     */
 | 
						|
    public Set<K> keySet()
 | 
						|
    {
 | 
						|
      if (keys == null)
 | 
						|
        keys = new UnmodifiableSet<K>(m.keySet());
 | 
						|
      return keys;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the addition of the entries in the supplied map.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param m The map, the entries of which should be added
 | 
						|
     *          to the underlying map.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         map does not support the <code>putAll</code> operation.
 | 
						|
     */
 | 
						|
    public void putAll(Map<? extends K, ? extends V> m)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Blocks the removal of an entry from the map.
 | 
						|
     * This method never returns, throwing an exception instead.
 | 
						|
     *
 | 
						|
     * @param o The key of the entry to remove.
 | 
						|
     * @return The value the key was associated with, or null
 | 
						|
     *         if no such mapping existed.  Null is also returned
 | 
						|
     *         if the removed entry had a null key.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         map does not support the <code>remove</code> operation.
 | 
						|
     */
 | 
						|
    public V remove(Object o)
 | 
						|
    {
 | 
						|
      throw new UnsupportedOperationException();
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of key-value mappings in the underlying map.
 | 
						|
     * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE
 | 
						|
     * is returned.
 | 
						|
     *
 | 
						|
     * @return the number of mappings.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return m.size();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a textual representation of the map.
 | 
						|
     *
 | 
						|
     * @return The map in the form of a <code>String</code>.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return m.toString();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable collection view of the values in the underlying map.
 | 
						|
     * The collection is backed by the map, so that changes in one show up in the other.
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  These modifications are again limited to the values of
 | 
						|
     * the keys.
 | 
						|
     *
 | 
						|
     * @return the collection view of all values.
 | 
						|
     */
 | 
						|
    public Collection<V> values()
 | 
						|
    {
 | 
						|
      if (values == null)
 | 
						|
        values = new UnmodifiableCollection<V>(m.values());
 | 
						|
      return values;
 | 
						|
    }
 | 
						|
  } // class UnmodifiableMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given set. This allows
 | 
						|
   * "read-only" access, although changes in the backing set show up
 | 
						|
   * in this view. Attempts to modify the set directly or via iterators
 | 
						|
   * will fail with {@link UnsupportedOperationException}.
 | 
						|
   * Although this view prevents changes to the structure of the set and its
 | 
						|
   * entries, the values referenced by the objects in the set can still be
 | 
						|
   * modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * The returned Set implements Serializable, but can only be serialized if
 | 
						|
   * the set it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param s the set to wrap
 | 
						|
   * @return a read-only view of the set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
 | 
						|
  {
 | 
						|
    return new UnmodifiableSet<T>(s);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableSet(Set)}. This class
 | 
						|
   * name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableSet<T> extends UnmodifiableCollection<T>
 | 
						|
    implements Set<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -9215047833775013803L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     * @param s the set to wrap
 | 
						|
     * @throws NullPointerException if s is null
 | 
						|
     */
 | 
						|
    UnmodifiableSet(Set<? extends T> s)
 | 
						|
    {
 | 
						|
      super(s);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is also an instance of
 | 
						|
     * <code>Set</code> of the same size and with the same entries.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if o is an equivalent set.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return c.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code of this set, as the sum of the
 | 
						|
     * hash codes of all elements within the set.
 | 
						|
     *
 | 
						|
     * @return the hash code of the set.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return c.hashCode();
 | 
						|
    }
 | 
						|
  } // class UnmodifiableSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given sorted map. This allows
 | 
						|
   * "read-only" access, although changes in the backing map show up in this
 | 
						|
   * view. Attempts to modify the map directly, via subviews, via collection
 | 
						|
   * views, or iterators, will fail with {@link UnsupportedOperationException}.
 | 
						|
   * Although this view prevents changes to the structure of the map and its
 | 
						|
   * entries, the values referenced by the objects in the map can still be
 | 
						|
   * modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * The returned SortedMap implements Serializable, but can only be
 | 
						|
   * serialized if the map it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param m the map to wrap
 | 
						|
   * @return a read-only view of the map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K,
 | 
						|
                                                             ? extends V> m)
 | 
						|
  {
 | 
						|
    return new UnmodifiableSortedMap<K, V>(m);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableSortedMap<K, V>
 | 
						|
    extends UnmodifiableMap<K, V>
 | 
						|
    implements SortedMap<K, V>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -8806743815996713206L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     * @serial the wrapped map
 | 
						|
     */
 | 
						|
    private final SortedMap<K, V> sm;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     * @param sm the map to wrap
 | 
						|
     * @throws NullPointerException if sm is null
 | 
						|
     */
 | 
						|
    UnmodifiableSortedMap(SortedMap<K, ? extends V> sm)
 | 
						|
    {
 | 
						|
      super(sm);
 | 
						|
      this.sm = (SortedMap<K,V>) sm;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying map,
 | 
						|
     * or null if it is the keys' natural ordering.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator.
 | 
						|
     */
 | 
						|
    public Comparator<? super K> comparator()
 | 
						|
    {
 | 
						|
      return sm.comparator();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first (lowest sorted) key in the map.
 | 
						|
     *
 | 
						|
     * @return the first key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K firstKey()
 | 
						|
    {
 | 
						|
      return sm.firstKey();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the map strictly less
 | 
						|
     * than toKey. The view is backed by the underlying map, so changes in
 | 
						|
     * one show up in the other.  The submap supports all optional operations
 | 
						|
     * of the original.  This operation is equivalent to
 | 
						|
     * <code>subMap(firstKey(), toKey)</code>.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of toKey. Note that the endpoint, toKey,
 | 
						|
     * is not included; if you want this value to be included, pass its successor
 | 
						|
     * object in to toKey.  For example, for Integers, you could request
 | 
						|
     * <code>headMap(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     *
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return the submap.
 | 
						|
     * @throws ClassCastException if toKey is not comparable to the map contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and toKey is out
 | 
						|
     *         of range.
 | 
						|
     * @throws NullPointerException if toKey is null but the map does not allow
 | 
						|
     *         null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> headMap(K toKey)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedMap<K, V>(sm.headMap(toKey));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last (highest sorted) key in the map.
 | 
						|
     *
 | 
						|
     * @return the last key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K lastKey()
 | 
						|
    {
 | 
						|
      return sm.lastKey();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the map greater than or
 | 
						|
     * equal to fromKey, and strictly less than toKey. The view is backed by
 | 
						|
     * the underlying map, so changes in one show up in the other. The submap
 | 
						|
     * supports all optional operations of the original.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of fromKey and toKey. Note that the
 | 
						|
     * lower endpoint is included, but the upper is not; if you want to
 | 
						|
     * change the inclusion or exclusion of an endpoint, pass its successor
 | 
						|
     * object in instead.  For example, for Integers, you could request
 | 
						|
     * <code>subMap(new Integer(lowlimit.intValue() + 1),
 | 
						|
     * new Integer(highlimit.intValue() + 1))</code> to reverse
 | 
						|
     * the inclusiveness of both endpoints.
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap.
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return the submap.
 | 
						|
     * @throws ClassCastException if fromKey or toKey is not comparable to
 | 
						|
     *         the map contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and fromKey or
 | 
						|
     *         toKey is out of range.
 | 
						|
     * @throws NullPointerException if fromKey or toKey is null but the map
 | 
						|
     *         does not allow null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> subMap(K fromKey, K toKey)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedMap<K, V>(sm.subMap(fromKey, toKey));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the map greater than or
 | 
						|
     * equal to fromKey. The view is backed by the underlying map, so changes
 | 
						|
     * in one show up in the other. The submap supports all optional operations
 | 
						|
     * of the original.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of fromKey. Note that the endpoint, fromKey, is
 | 
						|
     * included; if you do not want this value to be included, pass its successor object in
 | 
						|
     * to fromKey.  For example, for Integers, you could request
 | 
						|
     * <code>tailMap(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap
 | 
						|
     * @return the submap
 | 
						|
     * @throws ClassCastException if fromKey is not comparable to the map
 | 
						|
     *         contents
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and fromKey is out
 | 
						|
     *         of range
 | 
						|
     * @throws NullPointerException if fromKey is null but the map does not allow
 | 
						|
     *         null keys
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> tailMap(K fromKey)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedMap<K, V>(sm.tailMap(fromKey));
 | 
						|
    }
 | 
						|
  } // class UnmodifiableSortedMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an unmodifiable view of the given sorted set. This allows
 | 
						|
   * "read-only" access, although changes in the backing set show up
 | 
						|
   * in this view. Attempts to modify the set directly, via subsets, or via
 | 
						|
   * iterators, will fail with {@link UnsupportedOperationException}.
 | 
						|
   * Although this view prevents changes to the structure of the set and its
 | 
						|
   * entries, the values referenced by the objects in the set can still be
 | 
						|
   * modified.
 | 
						|
   * <p>
 | 
						|
   *
 | 
						|
   * The returns SortedSet implements Serializable, but can only be
 | 
						|
   * serialized if the set it wraps is likewise Serializable.
 | 
						|
   *
 | 
						|
   * @param s the set to wrap
 | 
						|
   * @return a read-only view of the set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
 | 
						|
  {
 | 
						|
    return new UnmodifiableSortedSet<T>(s);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  private static class UnmodifiableSortedSet<T> extends UnmodifiableSet<T>
 | 
						|
    implements SortedSet<T>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = -4929149591599911165L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped set; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     * @serial the wrapped set
 | 
						|
     */
 | 
						|
    private SortedSet<T> ss;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     * @param ss the set to wrap
 | 
						|
     * @throws NullPointerException if ss is null
 | 
						|
     */
 | 
						|
    UnmodifiableSortedSet(SortedSet<T> ss)
 | 
						|
    {
 | 
						|
      super(ss);
 | 
						|
      this.ss = ss;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying set,
 | 
						|
     * or null if it is the elements' natural ordering.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator
 | 
						|
     */
 | 
						|
    public Comparator<? super T> comparator()
 | 
						|
    {
 | 
						|
      return ss.comparator();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first (lowest sorted) element in the underlying
 | 
						|
     * set.
 | 
						|
     *
 | 
						|
     * @return the first element.
 | 
						|
     * @throws NoSuchElementException if the set is empty.
 | 
						|
     */
 | 
						|
    public T first()
 | 
						|
    {
 | 
						|
      return ss.first();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the set strictly
 | 
						|
     * less than toElement. The view is backed by the underlying set,
 | 
						|
     * so changes in one show up in the other.  The subset supports
 | 
						|
     * all optional operations of the original.  This operation
 | 
						|
     * is equivalent to <code>subSet(first(), toElement)</code>.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned set throws an IllegalArgumentException any time an element is
 | 
						|
     * used which is out of the range of toElement. Note that the endpoint, toElement,
 | 
						|
     * is not included; if you want this value included, pass its successor object in to
 | 
						|
     * toElement.  For example, for Integers, you could request
 | 
						|
     * <code>headSet(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     *
 | 
						|
     * @param toElement the exclusive upper range of the subset
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if toElement is not comparable to the set
 | 
						|
     *         contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and toElement is out
 | 
						|
     *         of range.
 | 
						|
     * @throws NullPointerException if toElement is null but the set does not
 | 
						|
     *         allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> headSet(T toElement)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedSet<T>(ss.headSet(toElement));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last (highest sorted) element in the underlying
 | 
						|
     * set.
 | 
						|
     *
 | 
						|
     * @return the last element.
 | 
						|
     * @throws NoSuchElementException if the set is empty.
 | 
						|
     */
 | 
						|
    public T last()
 | 
						|
    {
 | 
						|
      return ss.last();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the set greater than or
 | 
						|
     * equal to fromElement, and strictly less than toElement. The view is backed by
 | 
						|
     * the underlying set, so changes in one show up in the other. The subset
 | 
						|
     * supports all optional operations of the original.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned set throws an IllegalArgumentException any time an element is
 | 
						|
     * used which is out of the range of fromElement and toElement. Note that the
 | 
						|
     * lower endpoint is included, but the upper is not; if you want to
 | 
						|
     * change the inclusion or exclusion of an endpoint, pass its successor
 | 
						|
     * object in instead.  For example, for Integers, you can request
 | 
						|
     * <code>subSet(new Integer(lowlimit.intValue() + 1),
 | 
						|
     * new Integer(highlimit.intValue() + 1))</code> to reverse
 | 
						|
     * the inclusiveness of both endpoints.
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset.
 | 
						|
     * @param toElement the exclusive upper range of the subset.
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if fromElement or toElement is not comparable
 | 
						|
     *         to the set contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and fromElement or
 | 
						|
     *         toElement is out of range.
 | 
						|
     * @throws NullPointerException if fromElement or toElement is null but the
 | 
						|
     *         set does not allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> subSet(T fromElement, T toElement)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedSet<T>(ss.subSet(fromElement, toElement));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a unmodifiable view of the portion of the set greater than or equal to
 | 
						|
     * fromElement. The view is backed by the underlying set, so changes in one show up
 | 
						|
     * in the other. The subset supports all optional operations of the original.
 | 
						|
     * <p>
 | 
						|
     *
 | 
						|
     * The returned set throws an IllegalArgumentException any time an element is
 | 
						|
     * used which is out of the range of fromElement. Note that the endpoint,
 | 
						|
     * fromElement, is included; if you do not want this value to be included, pass its
 | 
						|
     * successor object in to fromElement.  For example, for Integers, you could request
 | 
						|
     * <code>tailSet(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if fromElement is not comparable to the set
 | 
						|
     *         contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and fromElement is
 | 
						|
     *         out of range.
 | 
						|
     * @throws NullPointerException if fromElement is null but the set does not
 | 
						|
     *         allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<T> tailSet(T fromElement)
 | 
						|
    {
 | 
						|
      return new UnmodifiableSortedSet<T>(ss.tailSet(fromElement));
 | 
						|
    }
 | 
						|
  } // class UnmodifiableSortedSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given collection,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * Since the collection might be a List or a Set, and those
 | 
						|
   * have incompatible equals and hashCode requirements, this relies
 | 
						|
   * on Object's implementation rather than passing those calls on to
 | 
						|
   * the wrapped collection. The returned Collection implements
 | 
						|
   * Serializable, but can only be serialized if the collection it
 | 
						|
   * wraps is likewise Serializable.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param c the collection to wrap in a dynamically typesafe wrapper
 | 
						|
   * @param type the type of elements the collection should hold.
 | 
						|
   * @return a dynamically typesafe view of the collection.
 | 
						|
   * @see Serializable
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  public static <E> Collection<E> checkedCollection(Collection<E> c,
 | 
						|
                                                    Class<E> type)
 | 
						|
  {
 | 
						|
    return new CheckedCollection<E>(c, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedCollection(Collection,Class)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedCollection<E>
 | 
						|
    implements Collection<E>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1578914078182001775L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped collection. Package visible for use by subclasses.
 | 
						|
     * @serial the real collection
 | 
						|
     */
 | 
						|
    final Collection<E> c;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The type of the elements of this collection.
 | 
						|
     * @serial the element type.
 | 
						|
     */
 | 
						|
    final Class<E> type;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given collection.
 | 
						|
     * @param c the collection to wrap
 | 
						|
     * @param type the type to wrap
 | 
						|
     * @throws NullPointerException if c is null
 | 
						|
     */
 | 
						|
    CheckedCollection(Collection<E> c, Class<E> type)
 | 
						|
    {
 | 
						|
      this.c = c;
 | 
						|
      this.type = type;
 | 
						|
      if (c == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the supplied object to the collection, on the condition that
 | 
						|
     * it is of the correct type.
 | 
						|
     *
 | 
						|
     * @param o the object to add.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result
 | 
						|
     *                           of this action.
 | 
						|
     * @throws ClassCastException if the object is not of the correct type.
 | 
						|
     */
 | 
						|
    public boolean add(E o)
 | 
						|
    {
 | 
						|
      if (type.isInstance(o))
 | 
						|
        return c.add(o);
 | 
						|
      else
 | 
						|
        throw new ClassCastException("The element is of the incorrect type.");
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the elements of the specified collection to the backing collection,
 | 
						|
     * provided they are all of the correct type.
 | 
						|
     *
 | 
						|
     * @param coll the collection to add.
 | 
						|
     * @return <code>true</code> if the collection was modified as a result
 | 
						|
     *                           of this action.
 | 
						|
     * @throws ClassCastException if <code>c</code> contained elements of an
 | 
						|
     *                            incorrect type.
 | 
						|
     */
 | 
						|
    public boolean addAll(Collection<? extends E> coll)
 | 
						|
    {
 | 
						|
      Collection<E> typedColl = (Collection<E>) c;
 | 
						|
      final Iterator<E> it = typedColl.iterator();
 | 
						|
      while (it.hasNext())
 | 
						|
        {
 | 
						|
          final E element = it.next();
 | 
						|
          if (!type.isInstance(element))
 | 
						|
            throw new ClassCastException("A member of the collection is not of the correct type.");
 | 
						|
        }
 | 
						|
      return c.addAll(typedColl);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all elements from the underlying collection.
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      c.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test whether the underlying collection contains a given object as one
 | 
						|
     * of its elements.
 | 
						|
     *
 | 
						|
     * @param o the element to look for.
 | 
						|
     * @return <code>true</code> if the underlying collection contains at least
 | 
						|
     *         one element e such that
 | 
						|
     *         <code>o == null ? e == null : o.equals(e)</code>.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid type for the
 | 
						|
     *         underlying collection.
 | 
						|
     * @throws NullPointerException if o is null and the underlying collection
 | 
						|
     *         doesn't support null values.
 | 
						|
     */
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return c.contains(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test whether the underlying collection contains every element in a given
 | 
						|
     * collection.
 | 
						|
     *
 | 
						|
     * @param coll the collection to test for.
 | 
						|
     * @return <code>true</code> if for every element o in c, contains(o) would
 | 
						|
     *         return <code>true</code>.
 | 
						|
     * @throws ClassCastException if the type of any element in c is not a
 | 
						|
     *                            valid type for the underlying collection.
 | 
						|
     * @throws NullPointerException if some element of c is null and the
 | 
						|
     *                              underlying collection does not support
 | 
						|
     *                              null values.
 | 
						|
     * @throws NullPointerException if c itself is null.
 | 
						|
     */
 | 
						|
    public boolean containsAll(Collection<?> coll)
 | 
						|
    {
 | 
						|
      return c.containsAll(coll);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether the underlying collection is empty, that is,
 | 
						|
     * if size() == 0.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if this collection contains no elements.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return c.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain an Iterator over the underlying collection, which maintains
 | 
						|
     * its checked nature.
 | 
						|
     *
 | 
						|
     * @return a Iterator over the elements of the underlying
 | 
						|
     *         collection, in any order.
 | 
						|
     */
 | 
						|
    public Iterator<E> iterator()
 | 
						|
    {
 | 
						|
      return new CheckedIterator<E>(c.iterator(), type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the supplied object from the collection, if it exists.
 | 
						|
     *
 | 
						|
     * @param o The object to remove.
 | 
						|
     * @return <code>true</code> if the object was removed (i.e. the underlying
 | 
						|
     *         collection returned 1 or more instances of o).
 | 
						|
     */
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      return c.remove(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all objects in the supplied collection from the backing
 | 
						|
     * collection, if they exist within it.
 | 
						|
     *
 | 
						|
     * @param coll the collection of objects to remove.
 | 
						|
     * @return <code>true</code> if the collection was modified.
 | 
						|
     */
 | 
						|
    public boolean removeAll(Collection<?> coll)
 | 
						|
    {
 | 
						|
      return c.removeAll(coll);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retains all objects specified by the supplied collection which exist
 | 
						|
     * within the backing collection, and removes all others.
 | 
						|
     *
 | 
						|
     * @param coll the collection of objects to retain.
 | 
						|
     * @return <code>true</code> if the collection was modified.
 | 
						|
     */
 | 
						|
    public boolean retainAll(Collection<?> coll)
 | 
						|
    {
 | 
						|
      return c.retainAll(coll);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the number of elements in the underlying collection.
 | 
						|
     *
 | 
						|
     * @return the number of elements in the collection.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return c.size();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copy the current contents of the underlying collection into an array.
 | 
						|
     *
 | 
						|
     * @return an array of type Object[] with a length equal to the size of the
 | 
						|
     *         underlying collection and containing the elements currently in
 | 
						|
     *         the underlying collection, in any order.
 | 
						|
     */
 | 
						|
    public Object[] toArray()
 | 
						|
    {
 | 
						|
      return c.toArray();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Copy the current contents of the underlying collection into an array. If
 | 
						|
     * the array passed as an argument has length less than the size of the
 | 
						|
     * underlying collection, an array of the same run-time type as a, with a
 | 
						|
     * length equal to the size of the underlying collection, is allocated
 | 
						|
     * using reflection.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * Otherwise, a itself is used.  The elements of the underlying collection
 | 
						|
     * are copied into it, and if there is space in the array, the following
 | 
						|
     * element is set to null. The resultant array is returned.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * <emph>Note</emph>: The fact that the following element is set to null
 | 
						|
     * is only useful if it is known that this collection does not contain
 | 
						|
     * any null elements.
 | 
						|
     *
 | 
						|
     * @param a the array to copy this collection into.
 | 
						|
     * @return an array containing the elements currently in the underlying
 | 
						|
     *         collection, in any order.
 | 
						|
     * @throws ArrayStoreException if the type of any element of the
 | 
						|
     *         collection is not a subtype of the element type of a.
 | 
						|
     */
 | 
						|
    public <S> S[] toArray(S[] a)
 | 
						|
    {
 | 
						|
      return c.toArray(a);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * A textual representation of the unmodifiable collection.
 | 
						|
     *
 | 
						|
     * @return The checked collection in the form of a <code>String</code>.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return c.toString();
 | 
						|
    }
 | 
						|
  } // class CheckedCollection
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of the various iterator methods in the
 | 
						|
   * checked classes.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedIterator<E>
 | 
						|
    implements Iterator<E>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The wrapped iterator.
 | 
						|
     */
 | 
						|
    private final Iterator<E> i;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The type of the elements of this collection.
 | 
						|
     * @serial the element type.
 | 
						|
     */
 | 
						|
    final Class<E> type;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper.
 | 
						|
     * @param i the wrapped iterator
 | 
						|
     * @param type the type of the elements within the checked list.
 | 
						|
     */
 | 
						|
    CheckedIterator(Iterator<E> i, Class<E> type)
 | 
						|
    {
 | 
						|
      this.i = i;
 | 
						|
      this.type = type;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains the next element in the underlying collection.
 | 
						|
     *
 | 
						|
     * @return the next element in the collection.
 | 
						|
     * @throws NoSuchElementException if there are no more elements.
 | 
						|
     */
 | 
						|
    public E next()
 | 
						|
    {
 | 
						|
      return i.next();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether there are still elements to be retrieved from the
 | 
						|
     * underlying collection by <code>next()</code>.  When this method
 | 
						|
     * returns <code>true</code>, an exception will not be thrown on calling
 | 
						|
     * <code>next()</code>.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if there is at least one more element in the
 | 
						|
     *         underlying collection.
 | 
						|
     */
 | 
						|
    public boolean hasNext()
 | 
						|
    {
 | 
						|
      return i.hasNext();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the next element from the collection.
 | 
						|
     */
 | 
						|
    public void remove()
 | 
						|
    {
 | 
						|
      i.remove();
 | 
						|
    }
 | 
						|
  } // class CheckedIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given list,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * The returned List implements Serializable, but can only be serialized if
 | 
						|
   * the list it wraps is likewise Serializable. In addition, if the wrapped
 | 
						|
   * list implements RandomAccess, this does too.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param l the list to wrap
 | 
						|
   * @param type the type of the elements within the checked list.
 | 
						|
   * @return a dynamically typesafe view of the list
 | 
						|
   * @see Serializable
 | 
						|
   * @see RandomAccess
 | 
						|
   */
 | 
						|
  public static <E> List<E> checkedList(List<E> l, Class<E> type)
 | 
						|
  {
 | 
						|
    if (l instanceof RandomAccess)
 | 
						|
      return new CheckedRandomAccessList<E>(l, type);
 | 
						|
    return new CheckedList<E>(l, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedList(List,Class)} for sequential
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedList<E>
 | 
						|
    extends CheckedCollection<E>
 | 
						|
    implements List<E>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 65247728283967356L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped list; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting. Package visible for use by subclass.
 | 
						|
     * @serial the wrapped list
 | 
						|
     */
 | 
						|
    final List<E> list;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @param type the type of the elements within the checked list.
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    CheckedList(List<E> l, Class<E> type)
 | 
						|
    {
 | 
						|
      super(l, type);
 | 
						|
      list = l;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the supplied element to the underlying list at the specified
 | 
						|
     * index, provided it is of the right type.
 | 
						|
     *
 | 
						|
     * @param index The index at which to place the new element.
 | 
						|
     * @param o the object to add.
 | 
						|
     * @throws ClassCastException if the type of the object is not a
 | 
						|
     *                            valid type for the underlying collection.
 | 
						|
     */
 | 
						|
    public void add(int index, E o)
 | 
						|
    {
 | 
						|
      if (type.isInstance(o))
 | 
						|
        list.add(index, o);
 | 
						|
      else
 | 
						|
        throw new ClassCastException("The object is of the wrong type.");
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the members of the supplied collection to the underlying
 | 
						|
     * collection at the specified index, provided they are all of the
 | 
						|
     * correct type.
 | 
						|
     *
 | 
						|
     * @param index the index at which to place the new element.
 | 
						|
     * @param coll the collections of objects to add.
 | 
						|
     * @throws ClassCastException if the type of any element in c is not a
 | 
						|
     *                            valid type for the underlying collection.
 | 
						|
     */
 | 
						|
    public boolean addAll(int index, Collection<? extends E> coll)
 | 
						|
    {
 | 
						|
      Collection<E> typedColl = (Collection<E>) coll;
 | 
						|
      final Iterator<E> it = typedColl.iterator();
 | 
						|
      while (it.hasNext())
 | 
						|
        {
 | 
						|
          if (!type.isInstance(it.next()))
 | 
						|
            throw new ClassCastException("A member of the collection is not of the correct type.");
 | 
						|
        }
 | 
						|
      return list.addAll(index, coll);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is an instance of
 | 
						|
     * <code>List</code> with the same size and elements
 | 
						|
     * as the underlying list.
 | 
						|
     *
 | 
						|
     * @param o The object to compare.
 | 
						|
     * @return <code>true</code> if o is equivalent to the underlying list.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return list.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Retrieves the element at a given index in the underlying list.
 | 
						|
     *
 | 
						|
     * @param index the index of the element to be returned
 | 
						|
     * @return the element at the specified index in the underlying list
 | 
						|
     * @throws IndexOutOfBoundsException if index < 0 || index >= size()
 | 
						|
     */
 | 
						|
    public E get(int index)
 | 
						|
    {
 | 
						|
      return list.get(index);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code for the underlying list.
 | 
						|
     * The exact computation is described in the documentation
 | 
						|
     * of the <code>List</code> interface.
 | 
						|
     *
 | 
						|
     * @return The hash code of the underlying list.
 | 
						|
     * @see List#hashCode()
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return list.hashCode();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the first index at which a given object is to be found in the
 | 
						|
     * underlying list.
 | 
						|
     *
 | 
						|
     * @param o the object to search for
 | 
						|
     * @return the least integer n such that <code>o == null ? get(n) == null :
 | 
						|
     *         o.equals(get(n))</code>, or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for the underlying list.
 | 
						|
     * @throws NullPointerException if o is null and the underlying
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
    public int indexOf(Object o)
 | 
						|
    {
 | 
						|
      return list.indexOf(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain the last index at which a given object is to be found in the
 | 
						|
     * underlying list.
 | 
						|
     *
 | 
						|
     * @return the greatest integer n such that
 | 
						|
     *         <code>o == null ? get(n) == null : o.equals(get(n))</code>,
 | 
						|
     *         or -1 if there is no such index.
 | 
						|
     * @throws ClassCastException if the type of o is not a valid
 | 
						|
     *         type for the underlying list.
 | 
						|
     * @throws NullPointerException if o is null and the underlying
 | 
						|
     *         list does not support null values.
 | 
						|
     */
 | 
						|
    public int lastIndexOf(Object o)
 | 
						|
    {
 | 
						|
      return list.lastIndexOf(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains a list iterator over the underlying list, starting at the
 | 
						|
     * beginning and maintaining the checked nature of this list.
 | 
						|
     *
 | 
						|
     * @return a <code>CheckedListIterator</code> over the elements of the
 | 
						|
     *         underlying list, in order, starting at the beginning.
 | 
						|
     */
 | 
						|
    public ListIterator<E> listIterator()
 | 
						|
    {
 | 
						|
      return new CheckedListIterator<E>(list.listIterator(), type);
 | 
						|
    }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Obtains a list iterator over the underlying list, starting at the
 | 
						|
   * specified index and maintaining the checked nature of this list.  An
 | 
						|
   * initial call to <code>next()</code> will retrieve the element at the
 | 
						|
   * specified index, and an initial call to <code>previous()</code> will
 | 
						|
   * retrieve the element at index - 1.
 | 
						|
   *
 | 
						|
   * @param index the position, between 0 and size() inclusive, to begin the
 | 
						|
   *        iteration from.
 | 
						|
   * @return a <code>CheckedListIterator</code> over the elements of the
 | 
						|
   *         underlying list, in order, starting at the specified index.
 | 
						|
   * @throws IndexOutOfBoundsException if index < 0 || index > size()
 | 
						|
   */
 | 
						|
    public ListIterator<E> listIterator(int index)
 | 
						|
    {
 | 
						|
      return new CheckedListIterator<E>(list.listIterator(index), type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the element at the specified index.
 | 
						|
     *
 | 
						|
     * @param index The index of the element to remove.
 | 
						|
     * @return the removed element.
 | 
						|
     */
 | 
						|
    public E remove(int index)
 | 
						|
    {
 | 
						|
      return list.remove(index);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Replaces the element at the specified index in the underlying list
 | 
						|
     * with that supplied.
 | 
						|
     *
 | 
						|
     * @param index the index of the element to replace.
 | 
						|
     * @param o the new object to place at the specified index.
 | 
						|
     * @return the replaced element.
 | 
						|
     */
 | 
						|
    public E set(int index, E o)
 | 
						|
    {
 | 
						|
      return list.set(index, o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtain a List view of a subsection of the underlying list, from
 | 
						|
     * fromIndex (inclusive) to toIndex (exclusive). If the two indices
 | 
						|
     * are equal, the sublist is empty. The returned list will be
 | 
						|
     * checked, like this list.  Changes to the elements of the
 | 
						|
     * returned list will be reflected in the underlying list. The effect
 | 
						|
     * of structural modifications is undefined.
 | 
						|
     *
 | 
						|
     * @param fromIndex the index that the returned list should start from
 | 
						|
     *        (inclusive).
 | 
						|
     * @param toIndex the index that the returned list should go
 | 
						|
     *                to (exclusive).
 | 
						|
     * @return a List backed by a subsection of the underlying list.
 | 
						|
     * @throws IndexOutOfBoundsException if fromIndex < 0
 | 
						|
     *         || toIndex > size() || fromIndex > toIndex.
 | 
						|
     */
 | 
						|
    public List<E> subList(int fromIndex, int toIndex)
 | 
						|
    {
 | 
						|
      return checkedList(list.subList(fromIndex, toIndex), type);
 | 
						|
    }
 | 
						|
  } // class CheckedList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedList(List)} for random-access
 | 
						|
   * lists. This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static final class CheckedRandomAccessList<E>
 | 
						|
    extends CheckedList<E>
 | 
						|
    implements RandomAccess
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1638200125423088369L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given list.
 | 
						|
     * @param l the list to wrap
 | 
						|
     * @param type the type of the elements within the checked list.
 | 
						|
     * @throws NullPointerException if l is null
 | 
						|
     */
 | 
						|
    CheckedRandomAccessList(List<E> l, Class<E> type)
 | 
						|
    {
 | 
						|
      super(l, type);
 | 
						|
    }
 | 
						|
  } // class CheckedRandomAccessList
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link CheckedList#listIterator()}.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static final class CheckedListIterator<E>
 | 
						|
    extends CheckedIterator<E>
 | 
						|
    implements ListIterator<E>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The wrapped iterator, stored both here and in the superclass to
 | 
						|
     * avoid excessive casting.
 | 
						|
     */
 | 
						|
    private final ListIterator<E> li;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Only trusted code creates a wrapper.
 | 
						|
     * @param li the wrapped iterator
 | 
						|
     */
 | 
						|
    CheckedListIterator(ListIterator<E> li, Class<E> type)
 | 
						|
    {
 | 
						|
      super(li, type);
 | 
						|
      this.li = li;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the supplied object at the current iterator position, provided
 | 
						|
     * it is of the correct type.
 | 
						|
     *
 | 
						|
     * @param o the object to add.
 | 
						|
     * @throws ClassCastException if the type of the object is not a
 | 
						|
     *                            valid type for the underlying collection.
 | 
						|
     */
 | 
						|
    public void add(E o)
 | 
						|
    {
 | 
						|
      if (type.isInstance(o))
 | 
						|
        li.add(o);
 | 
						|
      else
 | 
						|
        throw new ClassCastException("The object is of the wrong type.");
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests whether there are still elements to be retrieved from the
 | 
						|
     * underlying collection by <code>previous()</code>.  When this method
 | 
						|
     * returns <code>true</code>, an exception will not be thrown on calling
 | 
						|
     * <code>previous()</code>.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if there is at least one more element prior
 | 
						|
     *         to the current position in the underlying list.
 | 
						|
     */
 | 
						|
    public boolean hasPrevious()
 | 
						|
    {
 | 
						|
      return li.hasPrevious();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find the index of the element that would be returned by a call to next.
 | 
						|
     * If <code>hasNext()</code> returns <code>false</code>, this returns the
 | 
						|
     * list size.
 | 
						|
     *
 | 
						|
     * @return the index of the element that would be returned by
 | 
						|
     *         <code>next()</code>.
 | 
						|
     */
 | 
						|
    public int nextIndex()
 | 
						|
    {
 | 
						|
      return li.nextIndex();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Obtains the previous element in the underlying list.
 | 
						|
     *
 | 
						|
     * @return the previous element in the list.
 | 
						|
     * @throws NoSuchElementException if there are no more prior elements.
 | 
						|
     */
 | 
						|
    public E previous()
 | 
						|
    {
 | 
						|
      return li.previous();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Find the index of the element that would be returned by a call to
 | 
						|
     * previous. If <code>hasPrevious()</code> returns <code>false</code>,
 | 
						|
     * this returns -1.
 | 
						|
     *
 | 
						|
     * @return the index of the element that would be returned by
 | 
						|
     *         <code>previous()</code>.
 | 
						|
     */
 | 
						|
    public int previousIndex()
 | 
						|
    {
 | 
						|
      return li.previousIndex();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the next element to that supplied, provided that it is of the
 | 
						|
     * correct type.
 | 
						|
     *
 | 
						|
     * @param o The new object to replace the existing one.
 | 
						|
     * @throws ClassCastException if the type of the object is not a
 | 
						|
     *                            valid type for the underlying collection.
 | 
						|
     */
 | 
						|
    public void set(E o)
 | 
						|
    {
 | 
						|
      if (type.isInstance(o))
 | 
						|
        li.set(o);
 | 
						|
      else
 | 
						|
        throw new ClassCastException("The object is of the wrong type.");
 | 
						|
    }
 | 
						|
  } // class CheckedListIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given map,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * The returned Map implements Serializable, but can only be serialized if
 | 
						|
   * the map it wraps is likewise Serializable.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param m the map to wrap
 | 
						|
   * @param keyType the dynamic type of the map's keys.
 | 
						|
   * @param valueType the dynamic type of the map's values.
 | 
						|
   * @return a dynamically typesafe view of the map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType,
 | 
						|
                                            Class<V> valueType)
 | 
						|
  {
 | 
						|
    return new CheckedMap<K, V>(m, keyType, valueType);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedMap(Map)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedMap<K, V>
 | 
						|
    implements Map<K, V>, Serializable
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 5742860141034234728L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map.
 | 
						|
     * @serial the real map
 | 
						|
     */
 | 
						|
    private final Map<K, V> m;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The type of the map's keys.
 | 
						|
     * @serial the key type.
 | 
						|
     */
 | 
						|
    final Class<K> keyType;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The type of the map's values.
 | 
						|
     * @serial the value type.
 | 
						|
     */
 | 
						|
    final Class<V> valueType;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the entry set.
 | 
						|
     */
 | 
						|
    private transient Set<Map.Entry<K, V>> entries;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the key set.
 | 
						|
     */
 | 
						|
    private transient Set<K> keys;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cache the value collection.
 | 
						|
     */
 | 
						|
    private transient Collection<V> values;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     * @param m the map to wrap
 | 
						|
     * @param keyType the dynamic type of the map's keys.
 | 
						|
     * @param valueType the dynamic type of the map's values.
 | 
						|
     * @throws NullPointerException if m is null
 | 
						|
     */
 | 
						|
    CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType)
 | 
						|
    {
 | 
						|
      this.m = m;
 | 
						|
      this.keyType = keyType;
 | 
						|
      this.valueType = valueType;
 | 
						|
      if (m == null)
 | 
						|
        throw new NullPointerException();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Clears all pairs from the map.
 | 
						|
     */
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      m.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains a mapping for
 | 
						|
     * the given key.
 | 
						|
     *
 | 
						|
     * @param key the key to search for
 | 
						|
     * @return <code>true</code> if the map contains the key
 | 
						|
     * @throws ClassCastException if the key is of an inappropriate type
 | 
						|
     * @throws NullPointerException if key is <code>null</code> but the map
 | 
						|
     *         does not permit null keys
 | 
						|
     */
 | 
						|
    public boolean containsKey(Object key)
 | 
						|
    {
 | 
						|
      return m.containsKey(key);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains at least one
 | 
						|
     * mapping with the given value.  In other words, it returns
 | 
						|
     * <code>true</code> if a value v exists where
 | 
						|
     * <code>(value == null ? v == null : value.equals(v))</code>.
 | 
						|
     * This usually requires linear time.
 | 
						|
     *
 | 
						|
     * @param value the value to search for
 | 
						|
     * @return <code>true</code> if the map contains the value
 | 
						|
     * @throws ClassCastException if the type of the value is not a valid type
 | 
						|
     *         for this map.
 | 
						|
     * @throws NullPointerException if the value is null and the map doesn't
 | 
						|
     *         support null values.
 | 
						|
     */
 | 
						|
    public boolean containsValue(Object value)
 | 
						|
    {
 | 
						|
      return m.containsValue(value);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked set view of the entries in the underlying map.
 | 
						|
     * Each element in the set is a unmodifiable variant of
 | 
						|
     * <code>Map.Entry</code>.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The set is backed by the map, so that changes in one show up in the
 | 
						|
     * other.  Modifications made while an iterator is in progress cause
 | 
						|
     * undefined behavior.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @return the checked set view of all mapping entries.
 | 
						|
     * @see Map.Entry
 | 
						|
     */
 | 
						|
    public Set<Map.Entry<K, V>> entrySet()
 | 
						|
    {
 | 
						|
      if (entries == null)
 | 
						|
        {
 | 
						|
          Class<Map.Entry<K,V>> klass =
 | 
						|
            (Class<Map.Entry<K,V>>) (Class) Map.Entry.class;
 | 
						|
          entries = new CheckedEntrySet<Map.Entry<K,V>,K,V>(m.entrySet(),
 | 
						|
                                                            klass,
 | 
						|
                                                            keyType,
 | 
						|
                                                            valueType);
 | 
						|
        }
 | 
						|
      return entries;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * The implementation of {@link CheckedMap#entrySet()}. This class
 | 
						|
     * is <emph>not</emph> serializable.
 | 
						|
     *
 | 
						|
     * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
     * @since 1.5
 | 
						|
     */
 | 
						|
    private static final class CheckedEntrySet<E,SK,SV>
 | 
						|
      extends CheckedSet<E>
 | 
						|
    {
 | 
						|
      /**
 | 
						|
       * The type of the map's keys.
 | 
						|
       * @serial the key type.
 | 
						|
       */
 | 
						|
      private final Class<SK> keyType;
 | 
						|
 | 
						|
      /**
 | 
						|
       * The type of the map's values.
 | 
						|
       * @serial the value type.
 | 
						|
       */
 | 
						|
      private final Class<SV> valueType;
 | 
						|
 | 
						|
      /**
 | 
						|
       * Wrap a given set of map entries.
 | 
						|
       *
 | 
						|
       * @param s the set to wrap.
 | 
						|
       * @param type the type of the set's entries.
 | 
						|
       * @param keyType the type of the map's keys.
 | 
						|
       * @param valueType the type of the map's values.
 | 
						|
       */
 | 
						|
      CheckedEntrySet(Set<E> s, Class<E> type, Class<SK> keyType,
 | 
						|
                      Class<SV> valueType)
 | 
						|
      {
 | 
						|
        super(s, type);
 | 
						|
        this.keyType = keyType;
 | 
						|
        this.valueType = valueType;
 | 
						|
      }
 | 
						|
 | 
						|
      // The iterator must return checked map entries.
 | 
						|
      public Iterator<E> iterator()
 | 
						|
      {
 | 
						|
        return new CheckedIterator<E>(c.iterator(), type)
 | 
						|
        {
 | 
						|
          /**
 | 
						|
           * Obtains the next element from the underlying set of
 | 
						|
           * map entries.
 | 
						|
           *
 | 
						|
           * @return the next element in the collection.
 | 
						|
           * @throws NoSuchElementException if there are no more elements.
 | 
						|
           */
 | 
						|
          public E next()
 | 
						|
          {
 | 
						|
            final Map.Entry e = (Map.Entry) super.next();
 | 
						|
            return (E) new Map.Entry()
 | 
						|
            {
 | 
						|
              /**
 | 
						|
               * Returns <code>true</code> if the object, o, is also a map
 | 
						|
               * entry with an identical key and value.
 | 
						|
               *
 | 
						|
               * @param o the object to compare.
 | 
						|
               * @return <code>true</code> if o is an equivalent map entry.
 | 
						|
               */
 | 
						|
              public boolean equals(Object o)
 | 
						|
              {
 | 
						|
                return e.equals(o);
 | 
						|
              }
 | 
						|
 | 
						|
              /**
 | 
						|
               * Returns the key of this map entry.
 | 
						|
               *
 | 
						|
               * @return the key.
 | 
						|
               */
 | 
						|
              public Object getKey()
 | 
						|
              {
 | 
						|
                return e.getKey();
 | 
						|
              }
 | 
						|
 | 
						|
              /**
 | 
						|
               * Returns the value of this map entry.
 | 
						|
               *
 | 
						|
               * @return the value.
 | 
						|
               */
 | 
						|
              public Object getValue()
 | 
						|
              {
 | 
						|
                return e.getValue();
 | 
						|
              }
 | 
						|
 | 
						|
              /**
 | 
						|
               * Computes the hash code of this map entry.
 | 
						|
               * The computation is described in the <code>Map</code>
 | 
						|
               * interface documentation.
 | 
						|
               *
 | 
						|
               * @return the hash code of this entry.
 | 
						|
               * @see Map#hashCode()
 | 
						|
               */
 | 
						|
              public int hashCode()
 | 
						|
              {
 | 
						|
                return e.hashCode();
 | 
						|
              }
 | 
						|
 | 
						|
              /**
 | 
						|
               * Sets the value of this map entry, provided it is of the
 | 
						|
               * right type.
 | 
						|
               *
 | 
						|
               * @param value The new value.
 | 
						|
               * @throws ClassCastException if the type of the value is not
 | 
						|
               *                            a valid type for the underlying
 | 
						|
               *                             map.
 | 
						|
               */
 | 
						|
              public Object setValue(Object value)
 | 
						|
              {
 | 
						|
                if (valueType.isInstance(value))
 | 
						|
                  return e.setValue(value);
 | 
						|
                else
 | 
						|
                  throw new ClassCastException("The value is of the wrong type.");
 | 
						|
              }
 | 
						|
 | 
						|
              /**
 | 
						|
               * Returns a textual representation of the map entry.
 | 
						|
               *
 | 
						|
               * @return The map entry as a <code>String</code>.
 | 
						|
               */
 | 
						|
              public String toString()
 | 
						|
              {
 | 
						|
                return e.toString();
 | 
						|
              }
 | 
						|
            };
 | 
						|
          }
 | 
						|
        };
 | 
						|
      }
 | 
						|
    } // class CheckedEntrySet
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is also an instance
 | 
						|
     * of <code>Map</code> with an equal set of map entries.
 | 
						|
     *
 | 
						|
     * @param o The object to compare.
 | 
						|
     * @return <code>true</code> if o is an equivalent map.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return m.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the value associated with the supplied key or
 | 
						|
     * null if no such mapping exists.  An ambiguity can occur
 | 
						|
     * if null values are accepted by the underlying map.
 | 
						|
     * In this case, <code>containsKey()</code> can be used
 | 
						|
     * to separate the two possible cases of a null result.
 | 
						|
     *
 | 
						|
     * @param key The key to look up.
 | 
						|
     * @return the value associated with the key, or null if key not in map.
 | 
						|
     * @throws ClassCastException if the key is an inappropriate type.
 | 
						|
     * @throws NullPointerException if this map does not accept null keys.
 | 
						|
     * @see #containsKey(Object)
 | 
						|
     */
 | 
						|
    public V get(Object key)
 | 
						|
    {
 | 
						|
      return m.get(key);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds a new pair to the map, provided both the key and the value are
 | 
						|
     * of the correct types.
 | 
						|
     *
 | 
						|
     * @param key The new key.
 | 
						|
     * @param value The new value.
 | 
						|
     * @return the previous value of the key, or null if there was no mapping.
 | 
						|
     * @throws ClassCastException if the type of the key or the value is
 | 
						|
     *                            not a valid type for the underlying map.
 | 
						|
     */
 | 
						|
    public V put(K key, V value)
 | 
						|
    {
 | 
						|
      if (keyType.isInstance(key))
 | 
						|
        {
 | 
						|
          if (valueType.isInstance(value))
 | 
						|
            return m.put(key,value);
 | 
						|
          else
 | 
						|
            throw new ClassCastException("The value is of the wrong type.");
 | 
						|
        }
 | 
						|
      throw new ClassCastException("The key is of the wrong type.");
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code for the underlying map, as the sum
 | 
						|
     * of the hash codes of all entries.
 | 
						|
     *
 | 
						|
     * @return The hash code of the underlying map.
 | 
						|
     * @see Map.Entry#hashCode()
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return m.hashCode();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the underlying map contains no entries.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if the map is empty.
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return m.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked set view of the keys in the underlying map.
 | 
						|
     * The set is backed by the map, so that changes in one show up in the
 | 
						|
     * other.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  These modifications are again limited to the values of
 | 
						|
     * the keys.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @return the set view of all keys.
 | 
						|
     */
 | 
						|
    public Set<K> keySet()
 | 
						|
    {
 | 
						|
      if (keys == null)
 | 
						|
        keys = new CheckedSet<K>(m.keySet(), keyType);
 | 
						|
      return keys;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds all pairs within the supplied map to the underlying map,
 | 
						|
     * provided they are all have the correct key and value types.
 | 
						|
     *
 | 
						|
     * @param map the map, the entries of which should be added
 | 
						|
     *          to the underlying map.
 | 
						|
     * @throws ClassCastException if the type of a key or value is
 | 
						|
     *                            not a valid type for the underlying map.
 | 
						|
     */
 | 
						|
    public void putAll(Map<? extends K, ? extends V> map)
 | 
						|
    {
 | 
						|
      Map<K,V> typedMap = (Map<K,V>) map;
 | 
						|
      final Iterator<Map.Entry<K,V>> it = typedMap.entrySet().iterator();
 | 
						|
      while (it.hasNext())
 | 
						|
        {
 | 
						|
          final Map.Entry<K,V> entry = it.next();
 | 
						|
          if (!keyType.isInstance(entry.getKey()))
 | 
						|
            throw new ClassCastException("A key is of the wrong type.");
 | 
						|
          if (!valueType.isInstance(entry.getValue()))
 | 
						|
            throw new ClassCastException("A value is of the wrong type.");
 | 
						|
        }
 | 
						|
      m.putAll(typedMap);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes a pair from the map.
 | 
						|
     *
 | 
						|
     * @param o The key of the entry to remove.
 | 
						|
     * @return The value the key was associated with, or null
 | 
						|
     *         if no such mapping existed.  Null is also returned
 | 
						|
     *         if the removed entry had a null key.
 | 
						|
     * @throws UnsupportedOperationException as an unmodifiable
 | 
						|
     *         map does not support the <code>remove</code> operation.
 | 
						|
     */
 | 
						|
    public V remove(Object o)
 | 
						|
    {
 | 
						|
      return m.remove(o);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of key-value mappings in the underlying map.
 | 
						|
     * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE
 | 
						|
     * is returned.
 | 
						|
     *
 | 
						|
     * @return the number of mappings.
 | 
						|
     */
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return m.size();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a textual representation of the map.
 | 
						|
     *
 | 
						|
     * @return The map in the form of a <code>String</code>.
 | 
						|
     */
 | 
						|
    public String toString()
 | 
						|
    {
 | 
						|
      return m.toString();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a unmodifiable collection view of the values in the underlying
 | 
						|
     * map.  The collection is backed by the map, so that changes in one show
 | 
						|
     * up in the other.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * Modifications made while an iterator is in progress cause undefined
 | 
						|
     * behavior.  These modifications are again limited to the values of
 | 
						|
     * the keys.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @return the collection view of all values.
 | 
						|
     */
 | 
						|
    public Collection<V> values()
 | 
						|
    {
 | 
						|
      if (values == null)
 | 
						|
        values = new CheckedCollection<V>(m.values(), valueType);
 | 
						|
      return values;
 | 
						|
    }
 | 
						|
  } // class CheckedMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given set,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * The returned Set implements Serializable, but can only be serialized if
 | 
						|
   * the set it wraps is likewise Serializable.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param s the set to wrap.
 | 
						|
   * @param type the type of the elements within the checked list.
 | 
						|
   * @return a dynamically typesafe view of the set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <E> Set<E> checkedSet(Set<E> s, Class<E> type)
 | 
						|
  {
 | 
						|
    return new CheckedSet<E>(s, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedSet(Set)}. This class
 | 
						|
   * name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedSet<E>
 | 
						|
    extends CheckedCollection<E>
 | 
						|
    implements Set<E>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 4694047833775013803L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     *
 | 
						|
     * @param s the set to wrap
 | 
						|
     * @throws NullPointerException if s is null
 | 
						|
     */
 | 
						|
    CheckedSet(Set<E> s, Class<E> type)
 | 
						|
    {
 | 
						|
      super(s, type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the object, o, is also an instance of
 | 
						|
     * <code>Set</code> of the same size and with the same entries.
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if o is an equivalent set.
 | 
						|
     */
 | 
						|
    public boolean equals(Object o)
 | 
						|
    {
 | 
						|
      return c.equals(o);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Computes the hash code of this set, as the sum of the
 | 
						|
     * hash codes of all elements within the set.
 | 
						|
     *
 | 
						|
     * @return the hash code of the set.
 | 
						|
     */
 | 
						|
    public int hashCode()
 | 
						|
    {
 | 
						|
      return c.hashCode();
 | 
						|
    }
 | 
						|
  } // class CheckedSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given sorted map,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * The returned SortedMap implements Serializable, but can only be
 | 
						|
   * serialized if the map it wraps is likewise Serializable.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param m the map to wrap.
 | 
						|
   * @param keyType the dynamic type of the map's keys.
 | 
						|
   * @param valueType the dynamic type of the map's values.
 | 
						|
   * @return a dynamically typesafe view of the map
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m,
 | 
						|
                                                        Class<K> keyType,
 | 
						|
                                                        Class<V> valueType)
 | 
						|
  {
 | 
						|
    return new CheckedSortedMap<K, V>(m, keyType, valueType);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedSortedMap(SortedMap,Class,Class)}.
 | 
						|
   * This class name is required for compatibility with Sun's JDK
 | 
						|
   * serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   */
 | 
						|
  private static class CheckedSortedMap<K, V>
 | 
						|
    extends CheckedMap<K, V>
 | 
						|
    implements SortedMap<K, V>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.5.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1599671320688067438L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped map; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     * @serial the wrapped map
 | 
						|
     */
 | 
						|
    private final SortedMap<K, V> sm;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given map.
 | 
						|
     *
 | 
						|
     * @param sm the map to wrap
 | 
						|
     * @param keyType the dynamic type of the map's keys.
 | 
						|
     * @param valueType the dynamic type of the map's values.
 | 
						|
     * @throws NullPointerException if sm is null
 | 
						|
     */
 | 
						|
    CheckedSortedMap(SortedMap<K, V> sm, Class<K> keyType, Class<V> valueType)
 | 
						|
    {
 | 
						|
      super(sm, keyType, valueType);
 | 
						|
      this.sm = sm;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying map,
 | 
						|
     * or null if it is the keys' natural ordering.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator.
 | 
						|
     */
 | 
						|
    public Comparator<? super K> comparator()
 | 
						|
    {
 | 
						|
      return sm.comparator();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first (lowest sorted) key in the map.
 | 
						|
     *
 | 
						|
     * @return the first key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K firstKey()
 | 
						|
    {
 | 
						|
      return sm.firstKey();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the map strictly less
 | 
						|
     * than toKey. The view is backed by the underlying map, so changes in
 | 
						|
     * one show up in the other.  The submap supports all optional operations
 | 
						|
     * of the original.  This operation is equivalent to
 | 
						|
     * <code>subMap(firstKey(), toKey)</code>.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of toKey. Note that the endpoint, toKey,
 | 
						|
     * is not included; if you want this value to be included, pass its
 | 
						|
     * successor object in to toKey.  For example, for Integers, you could
 | 
						|
     * request <code>headMap(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return the submap.
 | 
						|
     * @throws ClassCastException if toKey is not comparable to the map
 | 
						|
     *                            contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and toKey is out
 | 
						|
     *         of range.
 | 
						|
     * @throws NullPointerException if toKey is null but the map does not allow
 | 
						|
     *         null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> headMap(K toKey)
 | 
						|
    {
 | 
						|
      return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last (highest sorted) key in the map.
 | 
						|
     *
 | 
						|
     * @return the last key.
 | 
						|
     * @throws NoSuchElementException if this map is empty.
 | 
						|
     */
 | 
						|
    public K lastKey()
 | 
						|
    {
 | 
						|
      return sm.lastKey();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the map greater than or
 | 
						|
     * equal to fromKey, and strictly less than toKey. The view is backed by
 | 
						|
     * the underlying map, so changes in one show up in the other. The submap
 | 
						|
     * supports all optional operations of the original.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of fromKey and toKey. Note that the
 | 
						|
     * lower endpoint is included, but the upper is not; if you want to
 | 
						|
     * change the inclusion or exclusion of an endpoint, pass its successor
 | 
						|
     * object in instead.  For example, for Integers, you could request
 | 
						|
     * <code>subMap(new Integer(lowlimit.intValue() + 1),
 | 
						|
     * new Integer(highlimit.intValue() + 1))</code> to reverse
 | 
						|
     * the inclusiveness of both endpoints.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap.
 | 
						|
     * @param toKey the exclusive upper range of the submap.
 | 
						|
     * @return the submap.
 | 
						|
     * @throws ClassCastException if fromKey or toKey is not comparable to
 | 
						|
     *         the map contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and fromKey or
 | 
						|
     *         toKey is out of range.
 | 
						|
     * @throws NullPointerException if fromKey or toKey is null but the map
 | 
						|
     *         does not allow null keys.
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> subMap(K fromKey, K toKey)
 | 
						|
    {
 | 
						|
      return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType,
 | 
						|
                                        valueType);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the map greater than or
 | 
						|
     * equal to fromKey. The view is backed by the underlying map, so changes
 | 
						|
     * in one show up in the other. The submap supports all optional operations
 | 
						|
     * of the original.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned map throws an IllegalArgumentException any time a key is
 | 
						|
     * used which is out of the range of fromKey. Note that the endpoint,
 | 
						|
     * fromKey, is included; if you do not want this value to be included,
 | 
						|
     * pass its successor object in to fromKey.  For example, for Integers,
 | 
						|
     * you could request
 | 
						|
     * <code>tailMap(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param fromKey the inclusive lower range of the submap
 | 
						|
     * @return the submap
 | 
						|
     * @throws ClassCastException if fromKey is not comparable to the map
 | 
						|
     *         contents
 | 
						|
     * @throws IllegalArgumentException if this is a subMap, and fromKey is out
 | 
						|
     *         of range
 | 
						|
     * @throws NullPointerException if fromKey is null but the map does not
 | 
						|
     *                              allow null keys
 | 
						|
     */
 | 
						|
    public SortedMap<K, V> tailMap(K fromKey)
 | 
						|
    {
 | 
						|
      return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType,
 | 
						|
                                        valueType);
 | 
						|
    }
 | 
						|
  } // class CheckedSortedMap
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>
 | 
						|
   * Returns a dynamically typesafe view of the given sorted set,
 | 
						|
   * where any modification is first checked to ensure that the type
 | 
						|
   * of the new data is appropriate.  Although the addition of
 | 
						|
   * generics and parametrically-typed collections prevents an
 | 
						|
   * incorrect type of element being added to a collection at
 | 
						|
   * compile-time, via static type checking, this can be overridden by
 | 
						|
   * casting.  In contrast, wrapping the collection within a
 | 
						|
   * dynamically-typesafe wrapper, using this and associated methods,
 | 
						|
   * <emph>guarantees</emph> that the collection will only contain
 | 
						|
   * elements of an appropriate type (provided it only contains such
 | 
						|
   * at the type of wrapping, and all subsequent access is via the
 | 
						|
   * wrapper).  This can be useful for debugging the cause of a
 | 
						|
   * <code>ClassCastException</code> caused by erroneous casting, or
 | 
						|
   * for protecting collections from corruption by external libraries.
 | 
						|
   * </p>
 | 
						|
   * <p>
 | 
						|
   * The returned SortedSet implements Serializable, but can only be
 | 
						|
   * serialized if the set it wraps is likewise Serializable.
 | 
						|
   * </p>
 | 
						|
   *
 | 
						|
   * @param s the set to wrap.
 | 
						|
   * @param type the type of the set's elements.
 | 
						|
   * @return a dynamically typesafe view of the set
 | 
						|
   * @see Serializable
 | 
						|
   */
 | 
						|
  public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
 | 
						|
                                                  Class<E> type)
 | 
						|
  {
 | 
						|
    return new CheckedSortedSet<E>(s, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #checkedSortedSet(SortedSet,Class)}. This
 | 
						|
   * class name is required for compatibility with Sun's JDK serializability.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.5
 | 
						|
   */
 | 
						|
  private static class CheckedSortedSet<E>
 | 
						|
    extends CheckedSet<E>
 | 
						|
    implements SortedSet<E>
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Compatible with JDK 1.4.
 | 
						|
     */
 | 
						|
    private static final long serialVersionUID = 1599911165492914959L;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The wrapped set; stored both here and in the superclass to avoid
 | 
						|
     * excessive casting.
 | 
						|
     *
 | 
						|
     * @serial the wrapped set
 | 
						|
     */
 | 
						|
    private SortedSet<E> ss;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Wrap a given set.
 | 
						|
     *
 | 
						|
     * @param ss the set to wrap.
 | 
						|
     * @param type the type of the set's elements.
 | 
						|
     * @throws NullPointerException if ss is null
 | 
						|
     */
 | 
						|
    CheckedSortedSet(SortedSet<E> ss, Class<E> type)
 | 
						|
    {
 | 
						|
      super(ss, type);
 | 
						|
      this.ss = ss;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the comparator used in sorting the underlying set,
 | 
						|
     * or null if it is the elements' natural ordering.
 | 
						|
     *
 | 
						|
     * @return the sorting comparator
 | 
						|
     */
 | 
						|
    public Comparator<? super E> comparator()
 | 
						|
    {
 | 
						|
      return ss.comparator();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the first (lowest sorted) element in the underlying
 | 
						|
     * set.
 | 
						|
     *
 | 
						|
     * @return the first element.
 | 
						|
     * @throws NoSuchElementException if the set is empty.
 | 
						|
     */
 | 
						|
    public E first()
 | 
						|
    {
 | 
						|
      return ss.first();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the set strictly
 | 
						|
     * less than toElement. The view is backed by the underlying set,
 | 
						|
     * so changes in one show up in the other.  The subset supports
 | 
						|
     * all optional operations of the original.  This operation
 | 
						|
     * is equivalent to <code>subSet(first(), toElement)</code>.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned set throws an IllegalArgumentException any time an
 | 
						|
     * element is used which is out of the range of toElement. Note that
 | 
						|
     * the endpoint, toElement, is not included; if you want this value
 | 
						|
     * included, pass its successor object in to toElement.  For example,
 | 
						|
     * for Integers, you could request
 | 
						|
     * <code>headSet(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param toElement the exclusive upper range of the subset
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if toElement is not comparable to the set
 | 
						|
     *         contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and toElement is
 | 
						|
     *                                  out of range.
 | 
						|
     * @throws NullPointerException if toElement is null but the set does not
 | 
						|
     *         allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<E> headSet(E toElement)
 | 
						|
    {
 | 
						|
      return new CheckedSortedSet<E>(ss.headSet(toElement), type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the last (highest sorted) element in the underlying
 | 
						|
     * set.
 | 
						|
     *
 | 
						|
     * @return the last element.
 | 
						|
     * @throws NoSuchElementException if the set is empty.
 | 
						|
     */
 | 
						|
    public E last()
 | 
						|
    {
 | 
						|
      return ss.last();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the set greater than or
 | 
						|
     * equal to fromElement, and strictly less than toElement. The view is
 | 
						|
     * backed by the underlying set, so changes in one show up in the other.
 | 
						|
     * The subset supports all optional operations of the original.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned set throws an IllegalArgumentException any time an
 | 
						|
     * element is used which is out of the range of fromElement and toElement.
 | 
						|
     * Note that the lower endpoint is included, but the upper is not; if you
 | 
						|
     * want to change the inclusion or exclusion of an endpoint, pass its
 | 
						|
     * successor object in instead.  For example, for Integers, you can request
 | 
						|
     * <code>subSet(new Integer(lowlimit.intValue() + 1),
 | 
						|
     * new Integer(highlimit.intValue() + 1))</code> to reverse
 | 
						|
     * the inclusiveness of both endpoints.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset.
 | 
						|
     * @param toElement the exclusive upper range of the subset.
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if fromElement or toElement is not comparable
 | 
						|
     *         to the set contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and fromElement or
 | 
						|
     *         toElement is out of range.
 | 
						|
     * @throws NullPointerException if fromElement or toElement is null but the
 | 
						|
     *         set does not allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<E> subSet(E fromElement, E toElement)
 | 
						|
    {
 | 
						|
      return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement), type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * <p>
 | 
						|
     * Returns a checked view of the portion of the set greater than or equal
 | 
						|
     * to fromElement. The view is backed by the underlying set, so changes in
 | 
						|
     * one show up in the other. The subset supports all optional operations
 | 
						|
     * of the original.
 | 
						|
     * </p>
 | 
						|
     * <p>
 | 
						|
     * The returned set throws an IllegalArgumentException any time an
 | 
						|
     * element is used which is out of the range of fromElement. Note that
 | 
						|
     * the endpoint, fromElement, is included; if you do not want this value
 | 
						|
     * to be included, pass its successor object in to fromElement.  For
 | 
						|
     * example, for Integers, you could request
 | 
						|
     * <code>tailSet(new Integer(limit.intValue() + 1))</code>.
 | 
						|
     * </p>
 | 
						|
     *
 | 
						|
     * @param fromElement the inclusive lower range of the subset
 | 
						|
     * @return the subset.
 | 
						|
     * @throws ClassCastException if fromElement is not comparable to the set
 | 
						|
     *         contents.
 | 
						|
     * @throws IllegalArgumentException if this is a subSet, and fromElement is
 | 
						|
     *         out of range.
 | 
						|
     * @throws NullPointerException if fromElement is null but the set does not
 | 
						|
     *         allow null elements.
 | 
						|
     */
 | 
						|
    public SortedSet<E> tailSet(E fromElement)
 | 
						|
    {
 | 
						|
      return new CheckedSortedSet<E>(ss.tailSet(fromElement), type);
 | 
						|
    }
 | 
						|
  } // class CheckedSortedSet
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a view of a {@link Deque} as a stack or LIFO (Last-In-First-Out)
 | 
						|
   * {@link Queue}.  Each call to the LIFO queue corresponds to one
 | 
						|
   * equivalent method call to the underlying deque, with the exception
 | 
						|
   * of {@link Collection#addAll(Collection)}, which is emulated by a series
 | 
						|
   * of {@link Deque#push(E)} calls.
 | 
						|
   *
 | 
						|
   * @param deque the deque to convert to a LIFO queue.
 | 
						|
   * @return a LIFO queue.
 | 
						|
   * @since 1.6
 | 
						|
   */
 | 
						|
  public static <T> Queue<T> asLifoQueue(Deque<T> deque)
 | 
						|
  {
 | 
						|
    return new LIFOQueue<T>(deque);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a set backed by the supplied map.  The resulting set
 | 
						|
   * has the same performance, concurrency and ordering characteristics
 | 
						|
   * as the original map.  The supplied map must be empty and should not
 | 
						|
   * be used after the set is created.  Each call to the set corresponds
 | 
						|
   * to one equivalent method call to the underlying map, with the exception
 | 
						|
   * of {@link Set#addAll(Collection)} which is emulated by a series of
 | 
						|
   * calls to <code>put</code>.
 | 
						|
   *
 | 
						|
   * @param map the map to convert to a set.
 | 
						|
   * @return a set backed by the supplied map.
 | 
						|
   * @throws IllegalArgumentException if the map is not empty.
 | 
						|
   * @since 1.6
 | 
						|
   */
 | 
						|
  public static <E> Set<E> newSetFromMap(Map<E,Boolean> map)
 | 
						|
  {
 | 
						|
    return new MapSet<E>(map);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #asLIFOQueue(Deque)}.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.6
 | 
						|
   */
 | 
						|
  private static class LIFOQueue<T>
 | 
						|
    extends AbstractQueue<T>
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * The backing deque.
 | 
						|
     */
 | 
						|
    private Deque<T> deque;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructs a new {@link LIFOQueue} with the specified
 | 
						|
     * backing {@link Deque}.
 | 
						|
     *
 | 
						|
     * @param deque the backing deque.
 | 
						|
     */
 | 
						|
    public LIFOQueue(Deque<T> deque)
 | 
						|
    {
 | 
						|
      this.deque = deque;
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean add(T e)
 | 
						|
    {
 | 
						|
      return deque.offerFirst(e);
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean addAll(Collection<? extends T> c)
 | 
						|
    {
 | 
						|
      boolean result = false;
 | 
						|
      final Iterator<? extends T> it = c.iterator();
 | 
						|
      while (it.hasNext())
 | 
						|
        result |= deque.offerFirst(it.next());
 | 
						|
      return result;
 | 
						|
    }
 | 
						|
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      deque.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return deque.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    public Iterator<T> iterator()
 | 
						|
    {
 | 
						|
      return deque.iterator();
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean offer(T e)
 | 
						|
    {
 | 
						|
      return deque.offerFirst(e);
 | 
						|
    }
 | 
						|
 | 
						|
    public T peek()
 | 
						|
    {
 | 
						|
      return deque.peek();
 | 
						|
    }
 | 
						|
 | 
						|
    public T poll()
 | 
						|
    {
 | 
						|
      return deque.poll();
 | 
						|
    }
 | 
						|
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return deque.size();
 | 
						|
    }
 | 
						|
  } // class LIFOQueue
 | 
						|
 | 
						|
  /**
 | 
						|
   * The implementation of {@link #newSetFromMap(Map)}.
 | 
						|
   *
 | 
						|
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 | 
						|
   * @since 1.6
 | 
						|
   */
 | 
						|
  private static class MapSet<E>
 | 
						|
    extends AbstractSet<E>
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * The backing map.
 | 
						|
     */
 | 
						|
    private Map<E,Boolean> map;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructs a new {@link MapSet} using the specified
 | 
						|
     * backing {@link Map}.
 | 
						|
     *
 | 
						|
     * @param map the backing map.
 | 
						|
     * @throws IllegalArgumentException if the map is not empty.
 | 
						|
     */
 | 
						|
    public MapSet(Map<E,Boolean> map)
 | 
						|
    {
 | 
						|
      if (!map.isEmpty())
 | 
						|
        throw new IllegalArgumentException("The map must be empty.");
 | 
						|
      this.map = map;
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean add(E e)
 | 
						|
    {
 | 
						|
      return map.put(e, true) == null;
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean addAll(Collection<? extends E> c)
 | 
						|
    {
 | 
						|
      boolean result = false;
 | 
						|
      final Iterator<? extends E> it = c.iterator();
 | 
						|
      while (it.hasNext())
 | 
						|
        result |= (map.put(it.next(), true) == null);
 | 
						|
      return result;
 | 
						|
    }
 | 
						|
 | 
						|
    public void clear()
 | 
						|
    {
 | 
						|
      map.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean contains(Object o)
 | 
						|
    {
 | 
						|
      return map.containsKey(o);
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return map.isEmpty();
 | 
						|
    }
 | 
						|
 | 
						|
    public Iterator<E> iterator()
 | 
						|
    {
 | 
						|
      return map.keySet().iterator();
 | 
						|
    }
 | 
						|
 | 
						|
    public boolean remove(Object o)
 | 
						|
    {
 | 
						|
      return map.remove(o) != null;
 | 
						|
    }
 | 
						|
 | 
						|
    public int size()
 | 
						|
    {
 | 
						|
      return map.size();
 | 
						|
    }
 | 
						|
  } // class MapSet
 | 
						|
 | 
						|
} // class Collections
 |