OSDN Git Service

* java/util/Collections.java (sort): Copy from array in forwards
[pf3gnuchains/gcc-fork.git] / libjava / java / util / Collections.java
1 /* Collections.java -- Utility class with methods to operate on collections
2    Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package java.util;
40
41 import java.io.Serializable;
42
43 /**
44  * Utility class consisting of static methods that operate on, or return
45  * Collections. Contains methods to sort, search, reverse, fill and shuffle
46  * Collections, methods to facilitate interoperability with legacy APIs that
47  * are unaware of collections, a method to return a list which consists of
48  * multiple copies of one element, and methods which "wrap" collections to give
49  * them extra properties, such as thread-safety and unmodifiability.
50  * <p>
51  *
52  * All methods which take a collection throw a {@link NullPointerException} if
53  * that collection is null. Algorithms which can change a collection may, but
54  * are not required, to throw the {@link UnsupportedOperationException} that
55  * the underlying collection would throw during an attempt at modification.
56  * For example,
57  * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code>
58  * does not throw a exception, even though addAll is an unsupported operation
59  * on a singleton; the reason for this is that addAll did not attempt to
60  * modify the set.
61  *
62  * @author Original author unknown
63  * @author Eric Blake <ebb9@email.byu.edu>
64  * @see Collection
65  * @see Set
66  * @see List
67  * @see Map
68  * @see Arrays
69  * @since 1.2
70  * @status updated to 1.4
71  */
72 public class Collections
73 {
74   /**
75    * Constant used to decide cutoff for when a non-RandomAccess list should
76    * be treated as sequential-access. Basically, quadratic behavior is
77    * acceptible for small lists when the overhead is so small in the first
78    * place. I arbitrarily set it to 16, so it may need some tuning.
79    */
80   private static final int LARGE_LIST_SIZE = 16;
81
82   /**
83    * Determines if a list should be treated as a sequential-access one.
84    * Rather than the old method of JDK 1.3 of assuming only instanceof
85    * AbstractSequentialList should be sequential, this uses the new method
86    * of JDK 1.4 of assuming anything that does NOT implement RandomAccess
87    * and exceeds a large (unspecified) size should be sequential.
88    *
89    * @param l the list to check
90    * @return true if it should be treated as sequential-access
91    */
92   private static boolean isSequential(List l)
93   {
94     return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE;
95   }
96
97   /**
98    * This class is non-instantiable.
99    */
100   private Collections()
101   {
102   }
103
104   /**
105    * An immutable, serializable, empty Set.
106    * @see Serializable
107    */
108   public static final Set EMPTY_SET = new EmptySet();
109
110   /**
111    * The implementation of {@link #EMPTY_SET}. This class name is required
112    * for compatibility with Sun's JDK serializability.
113    *
114    * @author Eric Blake <ebb9@email.byu.edu>
115    */
116   private static final class EmptySet extends AbstractSet
117     implements Serializable
118   {
119     /**
120      * Compatible with JDK 1.4.
121      */
122     private static final long serialVersionUID = 1582296315990362920L;
123
124     /**
125      * A private constructor adds overhead.
126      */
127     EmptySet()
128     {
129     }
130
131     /**
132      * The size: always 0!
133      */
134     public int size()
135     {
136       return 0;
137     }
138
139     /**
140      * Returns an iterator that does not iterate.
141      */
142     // This is really cheating! I think it's perfectly valid, though.
143     public Iterator iterator()
144     {
145       return EMPTY_LIST.iterator();
146     }
147
148     // The remaining methods are optional, but provide a performance
149     // advantage by not allocating unnecessary iterators in AbstractSet.
150     /**
151      * The empty set never contains anything.
152      */
153     public boolean contains(Object o)
154     {
155       return false;
156     }
157
158     /**
159      * This is true only if the given collection is also empty.
160      */
161     public boolean containsAll(Collection c)
162     {
163       return c.isEmpty();
164     }
165
166     /**
167      * Equal only if the other set is empty.
168      */
169     public boolean equals(Object o)
170     {
171       return o instanceof Set && ((Set) o).isEmpty();
172     }
173
174     /**
175      * The hashcode is always 0.
176      */
177     public int hashCode()
178     {
179       return 0;
180     }
181
182     /**
183      * Always succeeds with false result.
184      */
185     public boolean remove(Object o)
186     {
187       return false;
188     }
189
190     /**
191      * Always succeeds with false result.
192      */
193     public boolean removeAll(Collection c)
194     {
195       return false;
196     }
197
198     /**
199      * Always succeeds with false result.
200      */
201     public boolean retainAll(Collection c)
202     {
203       return false;
204     }
205
206     /**
207      * The array is always empty.
208      */
209     public Object[] toArray()
210     {
211       return new Object[0];
212     }
213
214     /**
215      * We don't even need to use reflection!
216      */
217     public Object[] toArray(Object[] a)
218     {
219       if (a.length > 0)
220         a[0] = null;
221       return a;
222     }
223
224     /**
225      * The string never changes.
226      */
227     public String toString()
228     {
229       return "[]";
230     }
231   } // class EmptySet
232
233   /**
234    * An immutable, serializable, empty List, which implements RandomAccess.
235    * @see Serializable
236    * @see RandomAccess
237    */
238   public static final List EMPTY_LIST = new EmptyList();
239
240   /**
241    * The implementation of {@link #EMPTY_LIST}. This class name is required
242    * for compatibility with Sun's JDK serializability.
243    *
244    * @author Eric Blake <ebb9@email.byu.edu>
245    */
246   private static final class EmptyList extends AbstractList
247     implements Serializable, RandomAccess
248   {
249     /**
250      * Compatible with JDK 1.4.
251      */
252     private static final long serialVersionUID = 8842843931221139166L;
253
254     /**
255      * A private constructor adds overhead.
256      */
257     EmptyList()
258     {
259     }
260
261     /**
262      * The size is always 0.
263      */
264     public int size()
265     {
266       return 0;
267     }
268
269     /**
270      * No matter the index, it is out of bounds.
271      */
272     public Object get(int index)
273     {
274       throw new IndexOutOfBoundsException();
275     }
276
277     // The remaining methods are optional, but provide a performance
278     // advantage by not allocating unnecessary iterators in AbstractList.
279     /**
280      * Never contains anything.
281      */
282     public boolean contains(Object o)
283     {
284       return false;
285     }
286
287     /**
288      * This is true only if the given collection is also empty.
289      */
290     public boolean containsAll(Collection c)
291     {
292       return c.isEmpty();
293     }
294
295     /**
296      * Equal only if the other set is empty.
297      */
298     public boolean equals(Object o)
299     {
300       return o instanceof List && ((List) o).isEmpty();
301     }
302
303     /**
304      * The hashcode is always 1.
305      */
306     public int hashCode()
307     {
308       return 1;
309     }
310
311     /**
312      * Returns -1.
313      */
314     public int indexOf(Object o)
315     {
316       return -1;
317     }
318
319     /**
320      * Returns -1.
321      */
322     public int lastIndexOf(Object o)
323     {
324       return -1;
325     }
326
327     /**
328      * Always succeeds with false result.
329      */
330     public boolean remove(Object o)
331     {
332       return false;
333     }
334
335     /**
336      * Always succeeds with false result.
337      */
338     public boolean removeAll(Collection c)
339     {
340       return false;
341     }
342
343     /**
344      * Always succeeds with false result.
345      */
346     public boolean retainAll(Collection c)
347     {
348       return false;
349     }
350
351     /**
352      * The array is always empty.
353      */
354     public Object[] toArray()
355     {
356       return new Object[0];
357     }
358
359     /**
360      * We don't even need to use reflection!
361      */
362     public Object[] toArray(Object[] a)
363     {
364       if (a.length > 0)
365         a[0] = null;
366       return a;
367     }
368
369     /**
370      * The string never changes.
371      */
372     public String toString()
373     {
374       return "[]";
375     }
376   } // class EmptyList
377
378   /**
379    * An immutable, serializable, empty Map.
380    * @see Serializable
381    */
382   public static final Map EMPTY_MAP = new EmptyMap();
383
384   /**
385    * The implementation of {@link #EMPTY_MAP}. This class name is required
386    * for compatibility with Sun's JDK serializability.
387    *
388    * @author Eric Blake <ebb9@email.byu.edu>
389    */
390   private static final class EmptyMap extends AbstractMap
391     implements Serializable
392   {
393     /**
394      * Compatible with JDK 1.4.
395      */
396     private static final long serialVersionUID = 6428348081105594320L;
397
398     /**
399      * A private constructor adds overhead.
400      */
401     EmptyMap()
402     {
403     }
404
405     /**
406      * There are no entries.
407      */
408     public Set entrySet()
409     {
410       return EMPTY_SET;
411     }
412
413     // The remaining methods are optional, but provide a performance
414     // advantage by not allocating unnecessary iterators in AbstractMap.
415     /**
416      * No entries!
417      */
418     public boolean containsKey(Object key)
419     {
420       return false;
421     }
422
423     /**
424      * No entries!
425      */
426     public boolean containsValue(Object value)
427     {
428       return false;
429     }
430
431     /**
432      * Equal to all empty maps.
433      */
434     public boolean equals(Object o)
435     {
436       return o instanceof Map && ((Map) o).isEmpty();
437     }
438
439     /**
440      * No mappings, so this returns null.
441      */
442     public Object get(Object o)
443     {
444       return null;
445     }
446
447     /**
448      * The hashcode is always 0.
449      */
450     public int hashCode()
451     {
452       return 0;
453     }
454
455     /**
456      * No entries.
457      */
458     public Set keySet()
459     {
460       return EMPTY_SET;
461     }
462
463     /**
464      * Remove always succeeds, with null result.
465      */
466     public Object remove(Object o)
467     {
468       return null;
469     }
470
471     /**
472      * Size is always 0.
473      */
474     public int size()
475     {
476       return 0;
477     }
478
479     /**
480      * No entries. Technically, EMPTY_SET, while more specific than a general
481      * Collection, will work. Besides, that's what the JDK uses!
482      */
483     public Collection values()
484     {
485       return EMPTY_SET;
486     }
487
488     /**
489      * The string never changes.
490      */
491     public String toString()
492     {
493       return "[]";
494     }
495   } // class EmptyMap
496
497 \f
498   /**
499    * Compare two objects with or without a Comparator. If c is null, uses the
500    * natural ordering. Slightly slower than doing it inline if the JVM isn't
501    * clever, but worth it for removing a duplicate of the search code.
502    * Note: This code is also used in Arrays (for sort as well as search).
503    */
504   static final int compare(Object o1, Object o2, Comparator c)
505   {
506     return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
507   }
508
509   /**
510    * Perform a binary search of a List for a key, using the natural ordering of
511    * the elements. The list must be sorted (as by the sort() method) - if it is
512    * not, the behavior of this method is undefined, and may be an infinite
513    * loop. Further, the key must be comparable with every item in the list. If
514    * the list contains the key more than once, any one of them may be found.
515    * <p>
516    *
517    * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
518    * and uses a linear search with O(n) link traversals and log(n) comparisons
519    * with {@link AbstractSequentialList} lists. Note: although the
520    * specification allows for an infinite loop if the list is unsorted, it will
521    * not happen in this (Classpath) implementation.
522    *
523    * @param l the list to search (must be sorted)
524    * @param key the value to search for
525    * @return the index at which the key was found, or -n-1 if it was not
526    *         found, where n is the index of the first value higher than key or
527    *         a.length if there is no such value
528    * @throws ClassCastException if key could not be compared with one of the
529    *         elements of l
530    * @throws NullPointerException if a null element has compareTo called
531    * @see #sort(List)
532    */
533   public static int binarySearch(List l, Object key)
534   {
535     return binarySearch(l, key, null);
536   }
537
538   /**
539    * Perform a binary search of a List for a key, using a supplied Comparator.
540    * The list must be sorted (as by the sort() method with the same Comparator)
541    * - if it is not, the behavior of this method is undefined, and may be an
542    * infinite loop. Further, the key must be comparable with every item in the
543    * list. If the list contains the key more than once, any one of them may be
544    * found. If the comparator is null, the elements' natural ordering is used.
545    * <p>
546    *
547    * This algorithm behaves in log(n) time for {@link RandomAccess} lists,
548    * and uses a linear search with O(n) link traversals and log(n) comparisons
549    * with {@link AbstractSequentialList} lists. Note: although the
550    * specification allows for an infinite loop if the list is unsorted, it will
551    * not happen in this (Classpath) implementation.
552    *
553    * @param l the list to search (must be sorted)
554    * @param key the value to search for
555    * @param c the comparator by which the list is sorted
556    * @return the index at which the key was found, or -n-1 if it was not
557    *         found, where n is the index of the first value higher than key or
558    *         a.length if there is no such value
559    * @throws ClassCastException if key could not be compared with one of the
560    *         elements of l
561    * @throws NullPointerException if a null element is compared with natural
562    *         ordering (only possible when c is null)
563    * @see #sort(List, Comparator)
564    */
565   public static int binarySearch(List l, Object key, Comparator c)
566   {
567     int pos = 0;
568     int low = 0;
569     int hi = l.size() - 1;
570
571     // We use a linear search with log(n) comparisons using an iterator
572     // if the list is sequential-access.
573     if (isSequential(l))
574       {
575         ListIterator itr = l.listIterator();
576         int i = 0;
577         Object o = itr.next(); // Assumes list is not empty (see isSequential)
578         boolean forward = true;
579         while (low <= hi)
580           {
581             pos = (low + hi) >> 1;
582             if (i < pos)
583               {
584                 if (!forward)
585                   itr.next(); // Changing direction first.
586                 for ( ; i != pos; i++, o = itr.next());
587                 forward = true;
588               }
589             else
590               {
591                 if (forward)
592                   itr.previous(); // Changing direction first.
593                 for ( ; i != pos; i--, o = itr.previous());
594                 forward = false;
595               }
596             final int d = compare(key, o, c);
597             if (d == 0)
598               return pos;
599             else if (d < 0)
600               hi = pos - 1;
601             else
602               // This gets the insertion point right on the last loop
603               low = ++pos;
604           }
605       }
606     else
607       {
608         while (low <= hi)
609           {
610             pos = (low + hi) >> 1;
611             final int d = compare(key, l.get(pos), c);
612             if (d == 0)
613               return pos;
614             else if (d < 0)
615               hi = pos - 1;
616             else
617               // This gets the insertion point right on the last loop
618               low = ++pos;
619           }
620       }
621
622     // If we failed to find it, we do the same whichever search we did.
623     return -pos - 1;
624   }
625
626   /**
627    * Copy one list to another. If the destination list is longer than the
628    * source list, the remaining elements are unaffected. This method runs in
629    * linear time.
630    *
631    * @param dest the destination list
632    * @param source the source list
633    * @throws IndexOutOfBoundsException if the destination list is shorter
634    *         than the source list (the destination will be unmodified)
635    * @throws UnsupportedOperationException if dest.listIterator() does not
636    *         support the set operation
637    */
638   public static void copy(List dest, List source)
639   {
640     int pos = source.size();
641     if (dest.size() < pos)
642       throw new IndexOutOfBoundsException("Source does not fit in dest");
643
644     Iterator i1 = source.iterator();
645     ListIterator i2 = dest.listIterator();
646
647     while (--pos >= 0)
648       {
649         i2.next();
650         i2.set(i1.next());
651       }
652   }
653
654   /**
655    * Returns an Enumeration over a collection. This allows interoperability
656    * with legacy APIs that require an Enumeration as input.
657    *
658    * @param c the Collection to iterate over
659    * @return an Enumeration backed by an Iterator over c
660    */
661   public static Enumeration enumeration(Collection c)
662   {
663     final Iterator i = c.iterator();
664     return new Enumeration()
665     {
666       public final boolean hasMoreElements()
667       {
668         return i.hasNext();
669       }
670       public final Object nextElement()
671       {
672         return i.next();
673       }
674     };
675   }
676
677   /**
678    * Replace every element of a list with a given value. This method runs in
679    * linear time.
680    *
681    * @param l the list to fill.
682    * @param val the object to vill the list with.
683    * @throws UnsupportedOperationException if l.listIterator() does not
684    *         support the set operation.
685    */
686   public static void fill(List l, Object val)
687   {
688     ListIterator itr = l.listIterator();
689     for (int i = l.size() - 1; i >= 0; --i)
690       {
691         itr.next();
692         itr.set(val);
693       }
694   }
695
696   /**
697    * Returns the starting index where the specified sublist first occurs
698    * in a larger list, or -1 if there is no matching position. If
699    * <code>target.size() &gt; source.size()</code>, this returns -1,
700    * otherwise this implementation uses brute force, checking for
701    * <code>source.sublist(i, i + target.size()).equals(target)</code>
702    * for all possible i.
703    *
704    * @param source the list to search
705    * @param target the sublist to search for
706    * @return the index where found, or -1
707    * @since 1.4
708    */
709   public static int indexOfSubList(List source, List target)
710   {
711     int ssize = source.size();
712     for (int i = 0, j = target.size(); j <= ssize; i++, j++)
713       if (source.subList(i, j).equals(target))
714         return i;
715     return -1;
716   }
717
718   /**
719    * Returns the starting index where the specified sublist last occurs
720    * in a larger list, or -1 if there is no matching position. If
721    * <code>target.size() &gt; source.size()</code>, this returns -1,
722    * otherwise this implementation uses brute force, checking for
723    * <code>source.sublist(i, i + target.size()).equals(target)</code>
724    * for all possible i.
725    *
726    * @param source the list to search
727    * @param target the sublist to search for
728    * @return the index where found, or -1
729    * @since 1.4
730    */
731   public static int lastIndexOfSubList(List source, List target)
732   {
733     int ssize = source.size();
734     for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--)
735       if (source.subList(i, j).equals(target))
736         return i;
737     return -1;
738   }
739
740   /**
741    * Returns an ArrayList holding the elements visited by a given
742    * Enumeration. This method exists for interoperability between legacy
743    * APIs and the new Collection API.
744    *
745    * @param e the enumeration to put in a list
746    * @return a list containing the enumeration elements
747    * @see ArrayList
748    * @since 1.4
749    */
750   public static ArrayList list(Enumeration e)
751   {
752     ArrayList l = new ArrayList();
753     while (e.hasMoreElements())
754       l.add(e.nextElement());
755     return l;
756   }
757
758   /**
759    * Find the maximum element in a Collection, according to the natural
760    * ordering of the elements. This implementation iterates over the
761    * Collection, so it works in linear time.
762    *
763    * @param c the Collection to find the maximum element of
764    * @return the maximum element of c
765    * @exception NoSuchElementException if c is empty
766    * @exception ClassCastException if elements in c are not mutually comparable
767    * @exception NullPointerException if null.compareTo is called
768    */
769   public static Object max(Collection c)
770   {
771     return max(c, null);
772   }
773
774   /**
775    * Find the maximum element in a Collection, according to a specified
776    * Comparator. This implementation iterates over the Collection, so it
777    * works in linear time.
778    *
779    * @param c the Collection to find the maximum element of
780    * @param order the Comparator to order the elements by, or null for natural
781    *        ordering
782    * @return the maximum element of c
783    * @throws NoSuchElementException if c is empty
784    * @throws ClassCastException if elements in c are not mutually comparable
785    * @throws NullPointerException if null is compared by natural ordering
786    *        (only possible when order is null)
787    */
788   public static Object max(Collection c, Comparator order)
789   {
790     Iterator itr = c.iterator();
791     Object max = itr.next(); // throws NoSuchElementException
792     int csize = c.size();
793     for (int i = 1; i < csize; i++)
794       {
795         Object o = itr.next();
796         if (compare(max, o, order) < 0)
797           max = o;
798       }
799     return max;
800   }
801
802   /**
803    * Find the minimum element in a Collection, according to the natural
804    * ordering of the elements. This implementation iterates over the
805    * Collection, so it works in linear time.
806    *
807    * @param c the Collection to find the minimum element of
808    * @return the minimum element of c
809    * @throws NoSuchElementException if c is empty
810    * @throws ClassCastException if elements in c are not mutually comparable
811    * @throws NullPointerException if null.compareTo is called
812    */
813   public static Object min(Collection c)
814   {
815     return min(c, null);
816   }
817
818   /**
819    * Find the minimum element in a Collection, according to a specified
820    * Comparator. This implementation iterates over the Collection, so it
821    * works in linear time.
822    *
823    * @param c the Collection to find the minimum element of
824    * @param order the Comparator to order the elements by, or null for natural
825    *        ordering
826    * @return the minimum element of c
827    * @throws NoSuchElementException if c is empty
828    * @throws ClassCastException if elements in c are not mutually comparable
829    * @throws NullPointerException if null is compared by natural ordering
830    *        (only possible when order is null)
831    */
832   public static Object min(Collection c, Comparator order)
833   {
834     Iterator itr = c.iterator();
835     Object min = itr.next();    // throws NoSuchElementExcception
836     int csize = c.size();
837     for (int i = 1; i < csize; i++)
838       {
839         Object o = itr.next();
840         if (compare(min, o, order) > 0)
841           min = o;
842       }
843     return min;
844   }
845
846   /**
847    * Creates an immutable list consisting of the same object repeated n times.
848    * The returned object is tiny, consisting of only a single reference to the
849    * object and a count of the number of elements. It is Serializable, and
850    * implements RandomAccess. You can use it in tandem with List.addAll for
851    * fast list construction.
852    *
853    * @param n the number of times to repeat the object
854    * @param o the object to repeat
855    * @return a List consisting of n copies of o
856    * @throws IllegalArgumentException if n &lt; 0
857    * @see List#addAll(Collection)
858    * @see Serializable
859    * @see RandomAccess
860    */
861   public static List nCopies(final int n, final Object o)
862   {
863     return new CopiesList(n, o);
864   }
865
866   /**
867    * The implementation of {@link #nCopies(int, Object)}. This class name
868    * is required for compatibility with Sun's JDK serializability.
869    *
870    * @author Eric Blake <ebb9@email.byu.edu>
871    */
872   private static final class CopiesList extends AbstractList
873     implements Serializable, RandomAccess
874   {
875     /**
876      * Compatible with JDK 1.4.
877      */
878     private static final long serialVersionUID = 2739099268398711800L;
879
880     /**
881      * The count of elements in this list.
882      * @serial the list size
883      */
884     private final int n;
885
886     /**
887      * The repeated list element.
888      * @serial the list contents
889      */
890     private final Object element;
891
892     /**
893      * Constructs the list.
894      *
895      * @param n the count
896      * @param o the object
897      * @throws IllegalArgumentException if n &lt; 0
898      */
899     CopiesList(int n, Object o)
900     {
901       if (n < 0)
902         throw new IllegalArgumentException();
903       this.n = n;
904       element = o;
905     }
906
907     /**
908      * The size is fixed.
909      */
910     public int size()
911     {
912       return n;
913     }
914
915     /**
916      * The same element is returned.
917      */
918     public Object get(int index)
919     {
920       if (index < 0 || index >= n)
921         throw new IndexOutOfBoundsException();
922       return element;
923     }
924
925     // The remaining methods are optional, but provide a performance
926     // advantage by not allocating unnecessary iterators in AbstractList.
927     /**
928      * This list only contains one element.
929      */
930     public boolean contains(Object o)
931     {
932       return n > 0 && equals(o, element);
933     }
934
935     /**
936      * The index is either 0 or -1.
937      */
938     public int indexOf(Object o)
939     {
940       return (n > 0 && equals(o, element)) ? 0 : -1;
941     }
942
943     /**
944      * The index is either n-1 or -1.
945      */
946     public int lastIndexOf(Object o)
947     {
948       return equals(o, element) ? n - 1 : -1;
949     }
950
951     /**
952      * A subList is just another CopiesList.
953      */
954     public List subList(int from, int to)
955     {
956       if (from < 0 || to > n)
957         throw new IndexOutOfBoundsException();
958       return new CopiesList(to - from, element);
959     }
960
961     /**
962      * The array is easy.
963      */
964     public Object[] toArray()
965     {
966       Object[] a = new Object[n];
967       Arrays.fill(a, element);
968       return a;
969     }
970
971     /**
972      * The string is easy to generate.
973      */
974     public String toString()
975     {
976       StringBuffer r = new StringBuffer("{");
977       for (int i = n - 1; --i > 0; )
978         r.append(element).append(", ");
979       r.append(element).append("}");
980       return r.toString();
981     }
982   } // class CopiesList
983
984   /**
985    * Replace all instances of one object with another in the specified list.
986    * The list does not change size. An element e is replaced if
987    * <code>oldval == null ? e == null : oldval.equals(e)</code>.
988    *
989    * @param list the list to iterate over
990    * @param oldval the element to replace
991    * @param newval the new value for the element
992    * @return true if a replacement occurred
993    * @throws UnsupportedOperationException if the list iterator does not allow
994    *         for the set operation
995    * @throws ClassCastException newval is of a type which cannot be added
996    *         to the list
997    * @throws IllegalArgumentException some other aspect of newval stops
998    *         it being added to the list
999    * @since 1.4
1000    */
1001   public static boolean replaceAll(List list, Object oldval, Object newval)
1002   {
1003     ListIterator itr = list.listIterator();
1004     boolean replace_occured = false;
1005     for (int i = list.size(); --i >= 0; )
1006       if (AbstractCollection.equals(oldval, itr.next()))
1007         {
1008           itr.set(newval);
1009           replace_occured = true;
1010         }
1011     return replace_occured;
1012   }
1013
1014   /**
1015    * Reverse a given list. This method works in linear time.
1016    *
1017    * @param l the list to reverse
1018    * @throws UnsupportedOperationException if l.listIterator() does not
1019    *         support the set operation
1020    */
1021   public static void reverse(List l)
1022   {
1023     ListIterator i1 = l.listIterator();
1024     int pos1 = 1;
1025     int pos2 = l.size();
1026     ListIterator i2 = l.listIterator(pos2);
1027     while (pos1 < pos2)
1028       {
1029         Object o = i1.next();
1030         i1.set(i2.previous());
1031         i2.set(o);
1032         ++pos1;
1033         --pos2;
1034       }
1035   }
1036
1037   /**
1038    * Get a comparator that implements the reverse of natural ordering. In
1039    * other words, this sorts Comparable objects opposite of how their
1040    * compareTo method would sort. This makes it easy to sort into reverse
1041    * order, by simply passing Collections.reverseOrder() to the sort method.
1042    * The return value of this method is Serializable.
1043    *
1044    * @return a comparator that imposes reverse natural ordering
1045    * @see Comparable
1046    * @see Serializable
1047    */
1048   public static Comparator reverseOrder()
1049   {
1050     return rcInstance;
1051   }
1052
1053   /**
1054    * The object for {@link #reverseOrder()}.
1055    */
1056   static private final ReverseComparator rcInstance = new ReverseComparator();
1057
1058   /**
1059    * The implementation of {@link #reverseOrder()}. This class name
1060    * is required for compatibility with Sun's JDK serializability.
1061    *
1062    * @author Eric Blake <ebb9@email.byu.edu>
1063    */
1064   private static final class ReverseComparator
1065     implements Comparator, Serializable
1066   {
1067     /**
1068      * Compatible with JDK 1.4.
1069      */
1070     static private final long serialVersionUID = 7207038068494060240L;
1071
1072     /**
1073      * A private constructor adds overhead.
1074      */
1075     ReverseComparator()
1076     {
1077     }
1078
1079     /**
1080      * Compare two objects in reverse natural order.
1081      *
1082      * @param a the first object
1083      * @param b the second object
1084      * @return &lt;, ==, or &gt; 0 according to b.compareTo(a)
1085      */
1086     public int compare(Object a, Object b)
1087     {
1088       return ((Comparable) b).compareTo(a);
1089     }
1090   }
1091
1092   /**
1093    * Rotate the elements in a list by a specified distance. After calling this
1094    * method, the element now at index <code>i</code> was formerly at index
1095    * <code>(i - distance) mod list.size()</code>. The list size is unchanged.
1096    * <p>
1097    *
1098    * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After
1099    * either <code>Collections.rotate(l, 4)</code> or
1100    * <code>Collections.rotate(l, -1)</code>, the new contents are
1101    * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate
1102    * just a portion of the list. For example, to move element <code>a</code>
1103    * forward two positions in the original example, use
1104    * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will
1105    * result in <code>[t, n, k, a, s]</code>.
1106    * <p>
1107    *
1108    * If the list is small or implements {@link RandomAccess}, the
1109    * implementation exchanges the first element to its destination, then the
1110    * displaced element, and so on until a circuit has been completed. The
1111    * process is repeated if needed on the second element, and so forth, until
1112    * all elements have been swapped.  For large non-random lists, the
1113    * implementation breaks the list into two sublists at index
1114    * <code>-distance mod size</code>, calls {@link #reverse(List)} on the
1115    * pieces, then reverses the overall list.
1116    *
1117    * @param list the list to rotate
1118    * @param distance the distance to rotate by; unrestricted in value
1119    * @throws UnsupportedOperationException if the list does not support set
1120    * @since 1.4
1121    */
1122   public static void rotate(List list, int distance)
1123   {
1124     int size = list.size();
1125     if (size == 0)
1126       return;
1127     distance %= size;
1128     if (distance == 0)
1129       return;
1130     if (distance < 0)
1131       distance += size;
1132
1133     if (isSequential(list))
1134       {
1135         reverse(list);
1136         reverse(list.subList(0, distance));
1137         reverse(list.subList(distance, size));
1138       }
1139     else
1140       {
1141         // Determine the least common multiple of distance and size, as there
1142         // are (distance / LCM) loops to cycle through.
1143         int a = size;
1144         int lcm = distance;
1145         int b = a % lcm;
1146         while (b != 0)
1147           {
1148             a = lcm;
1149             lcm = b;
1150             b = a % lcm;
1151           }
1152
1153         // Now, make the swaps. We must take the remainder every time through
1154         // the inner loop so that we don't overflow i to negative values.
1155         while (--lcm >= 0)
1156           {
1157             Object o = list.get(lcm);
1158             for (int i = lcm + distance; i != lcm; i = (i + distance) % size)
1159               o = list.set(i, o);
1160             list.set(lcm, o);
1161           }
1162       }
1163   }
1164
1165   /**
1166    * Shuffle a list according to a default source of randomness. The algorithm
1167    * used iterates backwards over the list, swapping each element with an
1168    * element randomly selected from the elements in positions less than or
1169    * equal to it (using r.nextInt(int)).
1170    * <p>
1171    *
1172    * This algorithm would result in a perfectly fair shuffle (that is, each
1173    * element would have an equal chance of ending up in any position) if r were
1174    * a perfect source of randomness. In practice the results are merely very
1175    * close to perfect.
1176    * <p>
1177    *
1178    * This method operates in linear time. To do this on large lists which do
1179    * not implement {@link RandomAccess}, a temporary array is used to acheive
1180    * this speed, since it would be quadratic access otherwise.
1181    *
1182    * @param l the list to shuffle
1183    * @throws UnsupportedOperationException if l.listIterator() does not
1184    *         support the set operation
1185    */
1186   public static void shuffle(List l)
1187   {
1188     if (defaultRandom == null)
1189       {
1190         synchronized (Collections.class)
1191         {
1192           if (defaultRandom == null)
1193             defaultRandom = new Random();
1194         }
1195       }
1196     shuffle(l, defaultRandom);
1197   }
1198
1199   /**
1200    * Cache a single Random object for use by shuffle(List). This improves
1201    * performance as well as ensuring that sequential calls to shuffle() will
1202    * not result in the same shuffle order occurring: the resolution of
1203    * System.currentTimeMillis() is not sufficient to guarantee a unique seed.
1204    */
1205   private static Random defaultRandom = null;
1206
1207   /**
1208    * Shuffle a list according to a given source of randomness. The algorithm
1209    * used iterates backwards over the list, swapping each element with an
1210    * element randomly selected from the elements in positions less than or
1211    * equal to it (using r.nextInt(int)).
1212    * <p>
1213    *
1214    * This algorithm would result in a perfectly fair shuffle (that is, each
1215    * element would have an equal chance of ending up in any position) if r were
1216    * a perfect source of randomness. In practise (eg if r = new Random()) the
1217    * results are merely very close to perfect.
1218    * <p>
1219    *
1220    * This method operates in linear time. To do this on large lists which do
1221    * not implement {@link RandomAccess}, a temporary array is used to acheive
1222    * this speed, since it would be quadratic access otherwise.
1223    *
1224    * @param l the list to shuffle
1225    * @param r the source of randomness to use for the shuffle
1226    * @throws UnsupportedOperationException if l.listIterator() does not
1227    *         support the set operation
1228    */
1229   public static void shuffle(List l, Random r)
1230   {
1231     int lsize = l.size();
1232     ListIterator i = l.listIterator(lsize);
1233     boolean sequential = isSequential(l);
1234     Object[] a = null; // stores a copy of the list for the sequential case
1235
1236     if (sequential)
1237       a = l.toArray();
1238
1239     for (int pos = lsize - 1; pos > 0; --pos)
1240       {
1241         // Obtain a random position to swap with. pos + 1 is used so that the
1242         // range of the random number includes the current position.
1243         int swap = r.nextInt(pos + 1);
1244
1245         // Swap the desired element.
1246         Object o;
1247         if (sequential)
1248           {
1249             o = a[swap];
1250             a[swap] = i.previous();
1251           }
1252         else
1253           o = l.set(swap, i.previous());
1254
1255         i.set(o);
1256       }
1257   }
1258
1259 \f
1260   /**
1261    * Obtain an immutable Set consisting of a single element. The return value
1262    * of this method is Serializable.
1263    *
1264    * @param o the single element
1265    * @return an immutable Set containing only o
1266    * @see Serializable
1267    */
1268   public static Set singleton(Object o)
1269   {
1270     return new SingletonSet(o);
1271   }
1272
1273   /**
1274    * The implementation of {@link #singleton(Object)}. This class name
1275    * is required for compatibility with Sun's JDK serializability.
1276    *
1277    * @author Eric Blake <ebb9@email.byu.edu>
1278    */
1279   private static final class SingletonSet extends AbstractSet
1280     implements Serializable
1281   {
1282     /**
1283      * Compatible with JDK 1.4.
1284      */
1285     private static final long serialVersionUID = 3193687207550431679L;
1286
1287
1288     /**
1289      * The single element; package visible for use in nested class.
1290      * @serial the singleton
1291      */
1292     final Object element;
1293
1294     /**
1295      * Construct a singleton.
1296      * @param o the element
1297      */
1298     SingletonSet(Object o)
1299     {
1300       element = o;
1301     }
1302
1303     /**
1304      * The size: always 1!
1305      */
1306     public int size()
1307     {
1308       return 1;
1309     }
1310
1311     /**
1312      * Returns an iterator over the lone element.
1313      */
1314     public Iterator iterator()
1315     {
1316       return new Iterator()
1317       {
1318         private boolean hasNext = true;
1319
1320         public boolean hasNext()
1321         {
1322           return hasNext;
1323         }
1324
1325         public Object next()
1326         {
1327           if (hasNext)
1328           {
1329             hasNext = false;
1330             return element;
1331           }
1332           else
1333             throw new NoSuchElementException();
1334         }
1335
1336         public void remove()
1337         {
1338           throw new UnsupportedOperationException();
1339         }
1340       };
1341     }
1342
1343     // The remaining methods are optional, but provide a performance
1344     // advantage by not allocating unnecessary iterators in AbstractSet.
1345     /**
1346      * The set only contains one element.
1347      */
1348     public boolean contains(Object o)
1349     {
1350       return equals(o, element);
1351     }
1352
1353     /**
1354      * This is true if the other collection only contains the element.
1355      */
1356     public boolean containsAll(Collection c)
1357     {
1358       Iterator i = c.iterator();
1359       int pos = c.size();
1360       while (--pos >= 0)
1361         if (! equals(i.next(), element))
1362           return false;
1363       return true;
1364     }
1365
1366     /**
1367      * The hash is just that of the element.
1368      */
1369     public int hashCode()
1370     {
1371       return hashCode(element);
1372     }
1373
1374     /**
1375      * Returning an array is simple.
1376      */
1377     public Object[] toArray()
1378     {
1379       return new Object[] {element};
1380     }
1381
1382     /**
1383      * Obvious string.
1384      */
1385     public String toString()
1386     {
1387       return "[" + element + "]";
1388     }
1389   } // class SingletonSet
1390
1391   /**
1392    * Obtain an immutable List consisting of a single element. The return value
1393    * of this method is Serializable, and implements RandomAccess.
1394    *
1395    * @param o the single element
1396    * @return an immutable List containing only o
1397    * @see Serializable
1398    * @see RandomAccess
1399    * @since 1.3
1400    */
1401   public static List singletonList(Object o)
1402   {
1403     return new SingletonList(o);
1404   }
1405
1406   /**
1407    * The implementation of {@link #singletonList(Object)}. This class name
1408    * is required for compatibility with Sun's JDK serializability.
1409    *
1410    * @author Eric Blake <ebb9@email.byu.edu>
1411    */
1412   private static final class SingletonList extends AbstractList
1413     implements Serializable, RandomAccess
1414   {
1415     /**
1416      * Compatible with JDK 1.4.
1417      */
1418     private static final long serialVersionUID = 3093736618740652951L;
1419
1420     /**
1421      * The single element.
1422      * @serial the singleton
1423      */
1424     private final Object element;
1425
1426     /**
1427      * Construct a singleton.
1428      * @param o the element
1429      */
1430     SingletonList(Object o)
1431     {
1432       element = o;
1433     }
1434
1435     /**
1436      * The size: always 1!
1437      */
1438     public int size()
1439     {
1440       return 1;
1441     }
1442
1443     /**
1444      * Only index 0 is valid.
1445      */
1446     public Object get(int index)
1447     {
1448       if (index == 0)
1449         return element;
1450       throw new IndexOutOfBoundsException();
1451     }
1452
1453     // The remaining methods are optional, but provide a performance
1454     // advantage by not allocating unnecessary iterators in AbstractList.
1455     /**
1456      * The set only contains one element.
1457      */
1458     public boolean contains(Object o)
1459     {
1460       return equals(o, element);
1461     }
1462
1463     /**
1464      * This is true if the other collection only contains the element.
1465      */
1466     public boolean containsAll(Collection c)
1467     {
1468       Iterator i = c.iterator();
1469       int pos = c.size();
1470       while (--pos >= 0)
1471         if (! equals(i.next(), element))
1472           return false;
1473       return true;
1474     }
1475
1476     /**
1477      * Speed up the hashcode computation.
1478      */
1479     public int hashCode()
1480     {
1481       return 31 + hashCode(element);
1482     }
1483
1484     /**
1485      * Either the list has it or not.
1486      */
1487     public int indexOf(Object o)
1488     {
1489       return equals(o, element) ? 0 : -1;
1490     }
1491
1492     /**
1493      * Either the list has it or not.
1494      */
1495     public int lastIndexOf(Object o)
1496     {
1497       return equals(o, element) ? 0 : -1;
1498     }
1499
1500     /**
1501      * Sublists are limited in scope.
1502      */
1503     public List subList(int from, int to)
1504     {
1505       if (from == to && (to == 0 || to == 1))
1506         return EMPTY_LIST;
1507       if (from == 0 && to == 1)
1508         return this;
1509       if (from > to)
1510         throw new IllegalArgumentException();
1511       throw new IndexOutOfBoundsException();
1512     }
1513
1514     /**
1515      * Returning an array is simple.
1516      */
1517     public Object[] toArray()
1518     {
1519       return new Object[] {element};
1520     }
1521
1522     /**
1523      * Obvious string.
1524      */
1525     public String toString()
1526     {
1527       return "[" + element + "]";
1528     }
1529   } // class SingletonList
1530
1531   /**
1532    * Obtain an immutable Map consisting of a single key-value pair.
1533    * The return value of this method is Serializable.
1534    *
1535    * @param key the single key
1536    * @param value the single value
1537    * @return an immutable Map containing only the single key-value pair
1538    * @see Serializable
1539    * @since 1.3
1540    */
1541   public static Map singletonMap(Object key, Object value)
1542   {
1543     return new SingletonMap(key, value);
1544   }
1545
1546   /**
1547    * The implementation of {@link #singletonMap(Object)}. This class name
1548    * is required for compatibility with Sun's JDK serializability.
1549    *
1550    * @author Eric Blake <ebb9@email.byu.edu>
1551    */
1552   private static final class SingletonMap extends AbstractMap
1553     implements Serializable
1554   {
1555     /**
1556      * Compatible with JDK 1.4.
1557      */
1558     private static final long serialVersionUID = -6979724477215052911L;
1559
1560     /**
1561      * The single key.
1562      * @serial the singleton key
1563      */
1564     private final Object k;
1565
1566     /**
1567      * The corresponding value.
1568      * @serial the singleton value
1569      */
1570     private final Object v;
1571
1572     /**
1573      * Cache the entry set.
1574      */
1575     private transient Set entries;
1576
1577     /**
1578      * Construct a singleton.
1579      * @param key the key
1580      * @param value the value
1581      */
1582     SingletonMap(Object key, Object value)
1583     {
1584       k = key;
1585       v = value;
1586     }
1587
1588     /**
1589      * There is a single immutable entry.
1590      */
1591     public Set entrySet()
1592     {
1593       if (entries == null)
1594         entries = singleton(new AbstractMap.BasicMapEntry(k, v)
1595         {
1596           public Object setValue(Object o)
1597           {
1598             throw new UnsupportedOperationException();
1599           }
1600         });
1601       return entries;
1602     }
1603
1604     // The remaining methods are optional, but provide a performance
1605     // advantage by not allocating unnecessary iterators in AbstractMap.
1606     /**
1607      * Single entry.
1608      */
1609     public boolean containsKey(Object key)
1610     {
1611       return equals(key, k);
1612     }
1613
1614     /**
1615      * Single entry.
1616      */
1617     public boolean containsValue(Object value)
1618     {
1619       return equals(value, v);
1620     }
1621
1622     /**
1623      * Single entry.
1624      */
1625     public Object get(Object key)
1626     {
1627       return equals(key, k) ? v : null;
1628     }
1629
1630     /**
1631      * Calculate the hashcode directly.
1632      */
1633     public int hashCode()
1634     {
1635       return hashCode(k) ^ hashCode(v);
1636     }
1637
1638     /**
1639      * Return the keyset.
1640      */
1641     public Set keySet()
1642     {
1643       if (keys == null)
1644         keys = singleton(k);
1645       return keys;
1646     }
1647
1648     /**
1649      * The size: always 1!
1650      */
1651     public int size()
1652     {
1653       return 1;
1654     }
1655
1656     /**
1657      * Return the values. Technically, a singleton, while more specific than
1658      * a general Collection, will work. Besides, that's what the JDK uses!
1659      */
1660     public Collection values()
1661     {
1662       if (values == null)
1663         values = singleton(v);
1664       return values;
1665     }
1666
1667     /**
1668      * Obvious string.
1669      */
1670     public String toString()
1671     {
1672       return "{" + k + "=" + v + "}";
1673     }
1674   } // class SingletonMap
1675
1676   /**
1677    * Sort a list according to the natural ordering of its elements. The list
1678    * must be modifiable, but can be of fixed size. The sort algorithm is
1679    * precisely that used by Arrays.sort(Object[]), which offers guaranteed
1680    * nlog(n) performance. This implementation dumps the list into an array,
1681    * sorts the array, and then iterates over the list setting each element from
1682    * the array.
1683    *
1684    * @param l the List to sort
1685    * @throws ClassCastException if some items are not mutually comparable
1686    * @throws UnsupportedOperationException if the List is not modifiable
1687    * @throws NullPointerException if some element is null
1688    * @see Arrays#sort(Object[])
1689    */
1690   public static void sort(List l)
1691   {
1692     sort(l, null);
1693   }
1694
1695   /**
1696    * Sort a list according to a specified Comparator. The list must be
1697    * modifiable, but can be of fixed size. The sort algorithm is precisely that
1698    * used by Arrays.sort(Object[], Comparator), which offers guaranteed
1699    * nlog(n) performance. This implementation dumps the list into an array,
1700    * sorts the array, and then iterates over the list setting each element from
1701    * the array.
1702    *
1703    * @param l the List to sort
1704    * @param c the Comparator specifying the ordering for the elements, or
1705    *        null for natural ordering
1706    * @throws ClassCastException if c will not compare some pair of items
1707    * @throws UnsupportedOperationException if the List is not modifiable
1708    * @throws NullPointerException if null is compared by natural ordering
1709    *        (only possible when c is null)
1710    * @see Arrays#sort(Object[], Comparator)
1711    */
1712   public static void sort(List l, Comparator c)
1713   {
1714     Object[] a = l.toArray();
1715     Arrays.sort(a, c);
1716     ListIterator i = l.listIterator();
1717     for (int pos = 0, alen = a.length;  pos < alen;  pos++)
1718       {
1719         i.next();
1720         i.set(a[pos]);
1721       }
1722   }
1723
1724   /**
1725    * Swaps the elements at the specified positions within the list. Equal
1726    * positions have no effect.
1727    *
1728    * @param l the list to work on
1729    * @param i the first index to swap
1730    * @param j the second index
1731    * @throws UnsupportedOperationException if list.set is not supported
1732    * @throws IndexOutOfBoundsException if either i or j is &lt; 0 or &gt;=
1733    *         list.size()
1734    * @since 1.4
1735    */
1736   public static void swap(List l, int i, int j)
1737   {
1738     l.set(i, l.set(j, l.get(i)));
1739   }
1740
1741 \f
1742   /**
1743    * Returns a synchronized (thread-safe) collection wrapper backed by the
1744    * given collection. Notice that element access through the iterators
1745    * is thread-safe, but if the collection can be structurally modified
1746    * (adding or removing elements) then you should synchronize around the
1747    * iteration to avoid non-deterministic behavior:<br>
1748    * <pre>
1749    * Collection c = Collections.synchronizedCollection(new Collection(...));
1750    * ...
1751    * synchronized (c)
1752    *   {
1753    *     Iterator i = c.iterator();
1754    *     while (i.hasNext())
1755    *       foo(i.next());
1756    *   }
1757    * </pre><p>
1758    *
1759    * Since the collection might be a List or a Set, and those have incompatible
1760    * equals and hashCode requirements, this relies on Object's implementation
1761    * rather than passing those calls on to the wrapped collection. The returned
1762    * Collection implements Serializable, but can only be serialized if
1763    * the collection it wraps is likewise Serializable.
1764    *
1765    * @param c the collection to wrap
1766    * @return a synchronized view of the collection
1767    * @see Serializable
1768    */
1769   public static Collection synchronizedCollection(Collection c)
1770   {
1771     return new SynchronizedCollection(c);
1772   }
1773
1774   /**
1775    * The implementation of {@link #synchronizedCollection(Collection)}. This
1776    * class name is required for compatibility with Sun's JDK serializability.
1777    * Package visible, so that collections such as the one for
1778    * Hashtable.values() can specify which object to synchronize on.
1779    *
1780    * @author Eric Blake <ebb9@email.byu.edu>
1781    */
1782   static class SynchronizedCollection
1783     implements Collection, Serializable
1784   {
1785     /**
1786      * Compatible with JDK 1.4.
1787      */
1788     private static final long serialVersionUID = 3053995032091335093L;
1789
1790     /**
1791      * The wrapped collection. Package visible for use by subclasses.
1792      * @serial the real collection
1793      */
1794     final Collection c;
1795
1796     /**
1797      * The object to synchronize on.  When an instance is created via public
1798      * methods, it will be this; but other uses like SynchronizedMap.values()
1799      * must specify another mutex. Package visible for use by subclasses.
1800      * @serial the lock
1801      */
1802     final Object mutex;
1803
1804     /**
1805      * Wrap a given collection.
1806      * @param c the collection to wrap
1807      * @throws NullPointerException if c is null
1808      */
1809     SynchronizedCollection(Collection c)
1810     {
1811       this.c = c;
1812       mutex = this;
1813       if (c == null)
1814         throw new NullPointerException();
1815     }
1816
1817     /**
1818      * Called only by trusted code to specify the mutex as well as the
1819      * collection.
1820      * @param sync the mutex
1821      * @param c the collection
1822      */
1823     SynchronizedCollection(Object sync, Collection c)
1824     {
1825       this.c = c;
1826       mutex = sync;
1827     }
1828
1829     public boolean add(Object o)
1830     {
1831       synchronized (mutex)
1832         {
1833           return c.add(o);
1834         }
1835     }
1836
1837     public boolean addAll(Collection col)
1838     {
1839       synchronized (mutex)
1840         {
1841           return c.addAll(col);
1842         }
1843     }
1844
1845     public void clear()
1846     {
1847       synchronized (mutex)
1848         {
1849           c.clear();
1850         }
1851     }
1852
1853     public boolean contains(Object o)
1854     {
1855       synchronized (mutex)
1856         {
1857           return c.contains(o);
1858         }
1859     }
1860
1861     public boolean containsAll(Collection c1)
1862     {
1863       synchronized (mutex)
1864         {
1865           return c.containsAll(c1);
1866         }
1867     }
1868
1869     public boolean isEmpty()
1870     {
1871       synchronized (mutex)
1872         {
1873           return c.isEmpty();
1874         }
1875     }
1876
1877     public Iterator iterator()
1878     {
1879       synchronized (mutex)
1880         {
1881           return new SynchronizedIterator(mutex, c.iterator());
1882         }
1883     }
1884
1885     public boolean remove(Object o)
1886     {
1887       synchronized (mutex)
1888         {
1889           return c.remove(o);
1890         }
1891     }
1892
1893     public boolean removeAll(Collection col)
1894     {
1895       synchronized (mutex)
1896         {
1897           return c.removeAll(col);
1898         }
1899     }
1900
1901     public boolean retainAll(Collection col)
1902     {
1903       synchronized (mutex)
1904         {
1905           return c.retainAll(col);
1906         }
1907     }
1908
1909     public int size()
1910     {
1911       synchronized (mutex)
1912         {
1913           return c.size();
1914         }
1915     }
1916
1917     public Object[] toArray()
1918     {
1919       synchronized (mutex)
1920         {
1921           return c.toArray();
1922         }
1923     }
1924
1925     public Object[] toArray(Object[] a)
1926     {
1927       synchronized (mutex)
1928         {
1929           return c.toArray(a);
1930         }
1931     }
1932
1933     public String toString()
1934     {
1935       synchronized (mutex)
1936         {
1937           return c.toString();
1938         }
1939     }
1940   } // class SynchronizedCollection
1941
1942   /**
1943    * The implementation of the various iterator methods in the
1944    * synchronized classes. These iterators must "sync" on the same object
1945    * as the collection they iterate over.
1946    *
1947    * @author Eric Blake <ebb9@email.byu.edu>
1948    */
1949   private static class SynchronizedIterator implements Iterator
1950   {
1951     /**
1952      * The object to synchronize on. Package visible for use by subclass.
1953      */
1954     final Object mutex;
1955
1956     /**
1957      * The wrapped iterator.
1958      */
1959     private final Iterator i;
1960
1961     /**
1962      * Only trusted code creates a wrapper, with the specified sync.
1963      * @param sync the mutex
1964      * @param i the wrapped iterator
1965      */
1966     SynchronizedIterator(Object sync, Iterator i)
1967     {
1968       this.i = i;
1969       mutex = sync;
1970     }
1971
1972     public Object next()
1973     {
1974       synchronized (mutex)
1975         {
1976           return i.next();
1977         }
1978     }
1979
1980     public boolean hasNext()
1981     {
1982       synchronized (mutex)
1983         {
1984           return i.hasNext();
1985         }
1986     }
1987
1988     public void remove()
1989     {
1990       synchronized (mutex)
1991         {
1992           i.remove();
1993         }
1994     }
1995   } // class SynchronizedIterator
1996
1997   /**
1998    * Returns a synchronized (thread-safe) list wrapper backed by the
1999    * given list. Notice that element access through the iterators
2000    * is thread-safe, but if the list can be structurally modified
2001    * (adding or removing elements) then you should synchronize around the
2002    * iteration to avoid non-deterministic behavior:<br>
2003    * <pre>
2004    * List l = Collections.synchronizedList(new List(...));
2005    * ...
2006    * synchronized (l)
2007    *   {
2008    *     Iterator i = l.iterator();
2009    *     while (i.hasNext())
2010    *       foo(i.next());
2011    *   }
2012    * </pre><p>
2013    *
2014    * The returned List implements Serializable, but can only be serialized if
2015    * the list it wraps is likewise Serializable. In addition, if the wrapped
2016    * list implements RandomAccess, this does too.
2017    *
2018    * @param l the list to wrap
2019    * @return a synchronized view of the list
2020    * @see Serializable
2021    * @see RandomAccess
2022    */
2023   public static List synchronizedList(List l)
2024   {
2025     if (l instanceof RandomAccess)
2026       return new SynchronizedRandomAccessList(l);
2027     return new SynchronizedList(l);
2028   }
2029
2030   /**
2031    * The implementation of {@link #synchronizedList(List)} for sequential
2032    * lists. This class name is required for compatibility with Sun's JDK
2033    * serializability. Package visible, so that lists such as Vector.subList()
2034    * can specify which object to synchronize on.
2035    *
2036    * @author Eric Blake <ebb9@email.byu.edu>
2037    */
2038   static class SynchronizedList extends SynchronizedCollection
2039     implements List
2040   {
2041     /**
2042      * Compatible with JDK 1.4.
2043      */
2044     private static final long serialVersionUID = -7754090372962971524L;
2045
2046     /**
2047      * The wrapped list; stored both here and in the superclass to avoid
2048      * excessive casting. Package visible for use by subclass.
2049      * @serial the wrapped list
2050      */
2051     final List list;
2052
2053     /**
2054      * Wrap a given list.
2055      * @param l the list to wrap
2056      * @throws NullPointerException if l is null
2057      */
2058     SynchronizedList(List l)
2059     {
2060       super(l);
2061       list = l;
2062     }
2063
2064     /**
2065      * Called only by trusted code to specify the mutex as well as the list.
2066      * @param sync the mutex
2067      * @param l the list
2068      */
2069     SynchronizedList(Object sync, List l)
2070     {
2071       super(sync, l);
2072       list = l;
2073     }
2074
2075     public void add(int index, Object o)
2076     {
2077       synchronized (mutex)
2078         {
2079           list.add(index, o);
2080         }
2081     }
2082
2083     public boolean addAll(int index, Collection c)
2084     {
2085       synchronized (mutex)
2086         {
2087           return list.addAll(index, c);
2088         }
2089     }
2090
2091     public boolean equals(Object o)
2092     {
2093       synchronized (mutex)
2094         {
2095           return list.equals(o);
2096         }
2097     }
2098
2099     public Object get(int index)
2100     {
2101       synchronized (mutex)
2102         {
2103           return list.get(index);
2104         }
2105     }
2106
2107     public int hashCode()
2108     {
2109       synchronized (mutex)
2110         {
2111           return list.hashCode();
2112         }
2113     }
2114
2115     public int indexOf(Object o)
2116     {
2117       synchronized (mutex)
2118         {
2119           return list.indexOf(o);
2120         }
2121     }
2122
2123     public int lastIndexOf(Object o)
2124     {
2125       synchronized (mutex)
2126         {
2127           return list.lastIndexOf(o);
2128         }
2129     }
2130
2131     public ListIterator listIterator()
2132     {
2133       synchronized (mutex)
2134         {
2135           return new SynchronizedListIterator(mutex, list.listIterator());
2136         }
2137     }
2138
2139     public ListIterator listIterator(int index)
2140     {
2141       synchronized (mutex)
2142         {
2143           return new SynchronizedListIterator(mutex, list.listIterator(index));
2144         }
2145     }
2146
2147     public Object remove(int index)
2148     {
2149       synchronized (mutex)
2150         {
2151           return list.remove(index);
2152         }
2153     }
2154
2155     public Object set(int index, Object o)
2156     {
2157       synchronized (mutex)
2158         {
2159           return list.set(index, o);
2160         }
2161     }
2162
2163     public List subList(int fromIndex, int toIndex)
2164     {
2165       synchronized (mutex)
2166         {
2167           return new SynchronizedList(mutex, list.subList(fromIndex, toIndex));
2168         }
2169     }
2170   } // class SynchronizedList
2171
2172   /**
2173    * The implementation of {@link #synchronizedList(List)} for random-access
2174    * lists. This class name is required for compatibility with Sun's JDK
2175    * serializability.
2176    *
2177    * @author Eric Blake <ebb9@email.byu.edu>
2178    */
2179   private static final class SynchronizedRandomAccessList
2180     extends SynchronizedList implements RandomAccess
2181   {
2182     /**
2183      * Compatible with JDK 1.4.
2184      */
2185     private static final long serialVersionUID = 1530674583602358482L;
2186
2187     /**
2188      * Wrap a given list.
2189      * @param l the list to wrap
2190      * @throws NullPointerException if l is null
2191      */
2192     SynchronizedRandomAccessList(List l)
2193     {
2194       super(l);
2195     }
2196
2197     /**
2198      * Called only by trusted code to specify the mutex as well as the
2199      * collection.
2200      * @param sync the mutex
2201      * @param l the list
2202      */
2203     SynchronizedRandomAccessList(Object sync, List l)
2204     {
2205       super(sync, l);
2206     }
2207
2208     public List subList(int fromIndex, int toIndex)
2209     {
2210       synchronized (mutex)
2211         {
2212           return new SynchronizedRandomAccessList(mutex,
2213                                                   list.subList(fromIndex,
2214                                                                toIndex));
2215         }
2216     }
2217   } // class SynchronizedRandomAccessList
2218
2219   /**
2220    * The implementation of {@link SynchronizedList#listIterator()}. This
2221    * iterator must "sync" on the same object as the list it iterates over.
2222    *
2223    * @author Eric Blake <ebb9@email.byu.edu>
2224    */
2225   private static final class SynchronizedListIterator
2226     extends SynchronizedIterator implements ListIterator
2227   {
2228     /**
2229      * The wrapped iterator, stored both here and in the superclass to
2230      * avoid excessive casting.
2231      */
2232     private final ListIterator li;
2233
2234     /**
2235      * Only trusted code creates a wrapper, with the specified sync.
2236      * @param sync the mutex
2237      * @param li the wrapped iterator
2238      */
2239     SynchronizedListIterator(Object sync, ListIterator li)
2240     {
2241       super(sync, li);
2242       this.li = li;
2243     }
2244
2245     public void add(Object o)
2246     {
2247       synchronized (mutex)
2248         {
2249           li.add(o);
2250         }
2251     }
2252     public boolean hasPrevious()
2253     {
2254       synchronized (mutex)
2255         {
2256           return li.hasPrevious();
2257         }
2258     }
2259
2260     public int nextIndex()
2261     {
2262       synchronized (mutex)
2263         {
2264           return li.nextIndex();
2265         }
2266     }
2267
2268     public Object previous()
2269     {
2270       synchronized (mutex)
2271         {
2272           return li.previous();
2273         }
2274     }
2275
2276     public int previousIndex()
2277     {
2278       synchronized (mutex)
2279         {
2280           return li.previousIndex();
2281         }
2282     }
2283
2284     public void set(Object o)
2285     {
2286       synchronized (mutex)
2287         {
2288           li.set(o);
2289         }
2290     }
2291   } // class SynchronizedListIterator
2292
2293   /**
2294    * Returns a synchronized (thread-safe) map wrapper backed by the given
2295    * map. Notice that element access through the collection views and their
2296    * iterators are thread-safe, but if the map can be structurally modified
2297    * (adding or removing elements) then you should synchronize around the
2298    * iteration to avoid non-deterministic behavior:<br>
2299    * <pre>
2300    * Map m = Collections.synchronizedMap(new Map(...));
2301    * ...
2302    * Set s = m.keySet(); // safe outside a synchronized block
2303    * synchronized (m) // synch on m, not s
2304    *   {
2305    *     Iterator i = s.iterator();
2306    *     while (i.hasNext())
2307    *       foo(i.next());
2308    *   }
2309    * </pre><p>
2310    *
2311    * The returned Map implements Serializable, but can only be serialized if
2312    * the map it wraps is likewise Serializable.
2313    *
2314    * @param m the map to wrap
2315    * @return a synchronized view of the map
2316    * @see Serializable
2317    */
2318   public static Map synchronizedMap(Map m)
2319   {
2320     return new SynchronizedMap(m);
2321   }
2322
2323   /**
2324    * The implementation of {@link #synchronizedMap(Map)}. This
2325    * class name is required for compatibility with Sun's JDK serializability.
2326    *
2327    * @author Eric Blake <ebb9@email.byu.edu>
2328    */
2329   private static class SynchronizedMap implements Map, Serializable
2330   {
2331     /**
2332      * Compatible with JDK 1.4.
2333      */
2334     private static final long serialVersionUID = 1978198479659022715L;
2335
2336     /**
2337      * The wrapped map.
2338      * @serial the real map
2339      */
2340     private final Map m;
2341
2342     /**
2343      * The object to synchronize on.  When an instance is created via public
2344      * methods, it will be this; but other uses like
2345      * SynchronizedSortedMap.subMap() must specify another mutex. Package
2346      * visible for use by subclass.
2347      * @serial the lock
2348      */
2349     final Object mutex;
2350
2351     /**
2352      * Cache the entry set.
2353      */
2354     private transient Set entries;
2355
2356     /**
2357      * Cache the key set.
2358      */
2359     private transient Set keys;
2360
2361     /**
2362      * Cache the value collection.
2363      */
2364     private transient Collection values;
2365
2366     /**
2367      * Wrap a given map.
2368      * @param m the map to wrap
2369      * @throws NullPointerException if m is null
2370      */
2371     SynchronizedMap(Map m)
2372     {
2373       this.m = m;
2374       mutex = this;
2375       if (m == null)
2376         throw new NullPointerException();
2377     }
2378
2379     /**
2380      * Called only by trusted code to specify the mutex as well as the map.
2381      * @param sync the mutex
2382      * @param m the map
2383      */
2384     SynchronizedMap(Object sync, Map m)
2385     {
2386       this.m = m;
2387       mutex = sync;
2388     }
2389
2390     public void clear()
2391     {
2392       synchronized (mutex)
2393         {
2394           m.clear();
2395         }
2396     }
2397
2398     public boolean containsKey(Object key)
2399     {
2400       synchronized (mutex)
2401         {
2402           return m.containsKey(key);
2403         }
2404     }
2405
2406     public boolean containsValue(Object value)
2407     {
2408       synchronized (mutex)
2409         {
2410           return m.containsValue(value);
2411         }
2412     }
2413
2414     // This is one of the ickiest cases of nesting I've ever seen. It just
2415     // means "return a SynchronizedSet, except that the iterator() method
2416     // returns an SynchronizedIterator whose next() method returns a
2417     // synchronized wrapper around its normal return value".
2418     public Set entrySet()
2419     {
2420       // Define this here to spare some nesting.
2421       class SynchronizedMapEntry implements Map.Entry
2422       {
2423         final Map.Entry e;
2424         SynchronizedMapEntry(Object o)
2425         {
2426           e = (Map.Entry) o;
2427         }
2428         public boolean equals(Object o)
2429         {
2430           synchronized (mutex)
2431             {
2432               return e.equals(o);
2433             }
2434         }
2435         public Object getKey()
2436         {
2437           synchronized (mutex)
2438             {
2439               return e.getKey();
2440             }
2441         }
2442         public Object getValue()
2443         {
2444           synchronized (mutex)
2445             {
2446               return e.getValue();
2447             }
2448         }
2449         public int hashCode()
2450         {
2451           synchronized (mutex)
2452             {
2453               return e.hashCode();
2454             }
2455         }
2456         public Object setValue(Object value)
2457         {
2458           synchronized (mutex)
2459             {
2460               return e.setValue(value);
2461             }
2462         }
2463         public String toString()
2464         {
2465           synchronized (mutex)
2466             {
2467               return e.toString();
2468             }
2469         }
2470       } // class SynchronizedMapEntry
2471
2472       // Now the actual code.
2473       if (entries == null)
2474         synchronized (mutex)
2475           {
2476             entries = new SynchronizedSet(mutex, m.entrySet())
2477             {
2478               public Iterator iterator()
2479               {
2480                 synchronized (super.mutex)
2481                   {
2482                     return new SynchronizedIterator(super.mutex, c.iterator())
2483                     {
2484                       public Object next()
2485                       {
2486                         synchronized (super.mutex)
2487                           {
2488                             return new SynchronizedMapEntry(super.next());
2489                           }
2490                       }
2491                     };
2492                   }
2493               }
2494             };
2495           }
2496       return entries;
2497     }
2498
2499     public boolean equals(Object o)
2500     {
2501       synchronized (mutex)
2502         {
2503           return m.equals(o);
2504         }
2505     }
2506
2507     public Object get(Object key)
2508     {
2509       synchronized (mutex)
2510         {
2511           return m.get(key);
2512         }
2513     }
2514
2515     public int hashCode()
2516     {
2517       synchronized (mutex)
2518         {
2519           return m.hashCode();
2520         }
2521     }
2522
2523     public boolean isEmpty()
2524     {
2525       synchronized (mutex)
2526         {
2527           return m.isEmpty();
2528         }
2529     }
2530
2531     public Set keySet()
2532     {
2533       if (keys == null)
2534         synchronized (mutex)
2535           {
2536             keys = new SynchronizedSet(mutex, m.keySet());
2537           }
2538       return keys;
2539     }
2540
2541     public Object put(Object key, Object value)
2542     {
2543       synchronized (mutex)
2544         {
2545           return m.put(key, value);
2546         }
2547     }
2548
2549     public void putAll(Map map)
2550     {
2551       synchronized (mutex)
2552         {
2553           m.putAll(map);
2554         }
2555     }
2556
2557     public Object remove(Object o)
2558     {
2559       synchronized (mutex)
2560         {
2561           return m.remove(o);
2562         }
2563     }
2564
2565     public int size()
2566     {
2567       synchronized (mutex)
2568         {
2569           return m.size();
2570         }
2571     }
2572
2573     public String toString()
2574     {
2575       synchronized (mutex)
2576         {
2577           return m.toString();
2578         }
2579     }
2580
2581     public Collection values()
2582     {
2583       if (values == null)
2584         synchronized (mutex)
2585           {
2586             values = new SynchronizedCollection(mutex, m.values());
2587           }
2588       return values;
2589     }
2590   } // class SynchronizedMap
2591
2592   /**
2593    * Returns a synchronized (thread-safe) set wrapper backed by the given
2594    * set. Notice that element access through the iterator is thread-safe, but
2595    * if the set can be structurally modified (adding or removing elements)
2596    * then you should synchronize around the iteration to avoid
2597    * non-deterministic behavior:<br>
2598    * <pre>
2599    * Set s = Collections.synchronizedSet(new Set(...));
2600    * ...
2601    * synchronized (s)
2602    *   {
2603    *     Iterator i = s.iterator();
2604    *     while (i.hasNext())
2605    *       foo(i.next());
2606    *   }
2607    * </pre><p>
2608    *
2609    * The returned Set implements Serializable, but can only be serialized if
2610    * the set it wraps is likewise Serializable.
2611    *
2612    * @param s the set to wrap
2613    * @return a synchronized view of the set
2614    * @see Serializable
2615    */
2616   public static Set synchronizedSet(Set s)
2617   {
2618     return new SynchronizedSet(s);
2619   }
2620
2621   /**
2622    * The implementation of {@link #synchronizedSet(Set)}. This class
2623    * name is required for compatibility with Sun's JDK serializability.
2624    * Package visible, so that sets such as Hashtable.keySet()
2625    * can specify which object to synchronize on.
2626    *
2627    * @author Eric Blake <ebb9@email.byu.edu>
2628    */
2629   static class SynchronizedSet extends SynchronizedCollection
2630     implements Set
2631   {
2632     /**
2633      * Compatible with JDK 1.4.
2634      */
2635     private static final long serialVersionUID = 487447009682186044L;
2636
2637     /**
2638      * Wrap a given set.
2639      * @param s the set to wrap
2640      * @throws NullPointerException if s is null
2641      */
2642     SynchronizedSet(Set s)
2643     {
2644       super(s);
2645     }
2646
2647     /**
2648      * Called only by trusted code to specify the mutex as well as the set.
2649      * @param sync the mutex
2650      * @param s the set
2651      */
2652     SynchronizedSet(Object sync, Set s)
2653     {
2654       super(sync, s);
2655     }
2656
2657     public boolean equals(Object o)
2658     {
2659       synchronized (mutex)
2660         {
2661           return c.equals(o);
2662         }
2663     }
2664
2665     public int hashCode()
2666     {
2667       synchronized (mutex)
2668         {
2669           return c.hashCode();
2670         }
2671     }
2672   } // class SynchronizedSet
2673
2674   /**
2675    * Returns a synchronized (thread-safe) sorted map wrapper backed by the
2676    * given map. Notice that element access through the collection views,
2677    * subviews, and their iterators are thread-safe, but if the map can be
2678    * structurally modified (adding or removing elements) then you should
2679    * synchronize around the iteration to avoid non-deterministic behavior:<br>
2680    * <pre>
2681    * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...));
2682    * ...
2683    * Set s = m.keySet(); // safe outside a synchronized block
2684    * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block
2685    * Set s2 = m2.keySet(); // safe outside a synchronized block
2686    * synchronized (m) // synch on m, not m2, s or s2
2687    *   {
2688    *     Iterator i = s.iterator();
2689    *     while (i.hasNext())
2690    *       foo(i.next());
2691    *     i = s2.iterator();
2692    *     while (i.hasNext())
2693    *       bar(i.next());
2694    *   }
2695    * </pre><p>
2696    *
2697    * The returned SortedMap implements Serializable, but can only be
2698    * serialized if the map it wraps is likewise Serializable.
2699    *
2700    * @param m the sorted map to wrap
2701    * @return a synchronized view of the sorted map
2702    * @see Serializable
2703    */
2704   public static SortedMap synchronizedSortedMap(SortedMap m)
2705   {
2706     return new SynchronizedSortedMap(m);
2707   }
2708
2709   /**
2710    * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
2711    * class name is required for compatibility with Sun's JDK serializability.
2712    *
2713    * @author Eric Blake <ebb9@email.byu.edu>
2714    */
2715   private static final class SynchronizedSortedMap extends SynchronizedMap
2716     implements SortedMap
2717   {
2718     /**
2719      * Compatible with JDK 1.4.
2720      */
2721     private static final long serialVersionUID = -8798146769416483793L;
2722
2723     /**
2724      * The wrapped map; stored both here and in the superclass to avoid
2725      * excessive casting.
2726      * @serial the wrapped map
2727      */
2728     private final SortedMap sm;
2729
2730     /**
2731      * Wrap a given map.
2732      * @param sm the map to wrap
2733      * @throws NullPointerException if sm is null
2734      */
2735     SynchronizedSortedMap(SortedMap sm)
2736     {
2737       super(sm);
2738       this.sm = sm;
2739     }
2740
2741     /**
2742      * Called only by trusted code to specify the mutex as well as the map.
2743      * @param sync the mutex
2744      * @param sm the map
2745      */
2746     SynchronizedSortedMap(Object sync, SortedMap sm)
2747     {
2748       super(sync, sm);
2749       this.sm = sm;
2750     }
2751
2752     public Comparator comparator()
2753     {
2754       synchronized (mutex)
2755         {
2756           return sm.comparator();
2757         }
2758     }
2759
2760     public Object firstKey()
2761     {
2762       synchronized (mutex)
2763         {
2764           return sm.firstKey();
2765         }
2766     }
2767
2768     public SortedMap headMap(Object toKey)
2769     {
2770       synchronized (mutex)
2771         {
2772           return new SynchronizedSortedMap(mutex, sm.headMap(toKey));
2773         }
2774     }
2775
2776     public Object lastKey()
2777     {
2778       synchronized (mutex)
2779         {
2780           return sm.lastKey();
2781         }
2782     }
2783
2784     public SortedMap subMap(Object fromKey, Object toKey)
2785     {
2786       synchronized (mutex)
2787         {
2788           return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey));
2789         }
2790     }
2791
2792     public SortedMap tailMap(Object fromKey)
2793     {
2794       synchronized (mutex)
2795         {
2796           return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey));
2797         }
2798     }
2799   } // class SynchronizedSortedMap
2800
2801   /**
2802    * Returns a synchronized (thread-safe) sorted set wrapper backed by the
2803    * given set. Notice that element access through the iterator and through
2804    * subviews are thread-safe, but if the set can be structurally modified
2805    * (adding or removing elements) then you should synchronize around the
2806    * iteration to avoid non-deterministic behavior:<br>
2807    * <pre>
2808    * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...));
2809    * ...
2810    * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block
2811    * synchronized (s) // synch on s, not s2
2812    *   {
2813    *     Iterator i = s2.iterator();
2814    *     while (i.hasNext())
2815    *       foo(i.next());
2816    *   }
2817    * </pre><p>
2818    *
2819    * The returned SortedSet implements Serializable, but can only be
2820    * serialized if the set it wraps is likewise Serializable.
2821    *
2822    * @param s the sorted set to wrap
2823    * @return a synchronized view of the sorted set
2824    * @see Serializable
2825    */
2826   public static SortedSet synchronizedSortedSet(SortedSet s)
2827   {
2828     return new SynchronizedSortedSet(s);
2829   }
2830
2831   /**
2832    * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This
2833    * class name is required for compatibility with Sun's JDK serializability.
2834    *
2835    * @author Eric Blake <ebb9@email.byu.edu>
2836    */
2837   private static final class SynchronizedSortedSet extends SynchronizedSet
2838     implements SortedSet
2839   {
2840     /**
2841      * Compatible with JDK 1.4.
2842      */
2843     private static final long serialVersionUID = 8695801310862127406L;
2844
2845     /**
2846      * The wrapped set; stored both here and in the superclass to avoid
2847      * excessive casting.
2848      * @serial the wrapped set
2849      */
2850     private final SortedSet ss;
2851
2852     /**
2853      * Wrap a given set.
2854      * @param ss the set to wrap
2855      * @throws NullPointerException if ss is null
2856      */
2857     SynchronizedSortedSet(SortedSet ss)
2858     {
2859       super(ss);
2860       this.ss = ss;
2861     }
2862
2863     /**
2864      * Called only by trusted code to specify the mutex as well as the set.
2865      * @param sync the mutex
2866      * @param l the list
2867      */
2868     SynchronizedSortedSet(Object sync, SortedSet ss)
2869     {
2870       super(sync, ss);
2871       this.ss = ss;
2872     }
2873
2874     public Comparator comparator()
2875     {
2876       synchronized (mutex)
2877         {
2878           return ss.comparator();
2879         }
2880     }
2881
2882     public Object first()
2883     {
2884       synchronized (mutex)
2885         {
2886           return ss.first();
2887         }
2888     }
2889
2890     public SortedSet headSet(Object toElement)
2891     {
2892       synchronized (mutex)
2893         {
2894           return new SynchronizedSortedSet(mutex, ss.headSet(toElement));
2895         }
2896     }
2897
2898     public Object last()
2899     {
2900       synchronized (mutex)
2901         {
2902           return ss.last();
2903         }
2904     }
2905
2906     public SortedSet subSet(Object fromElement, Object toElement)
2907     {
2908       synchronized (mutex)
2909         {
2910           return new SynchronizedSortedSet(mutex,
2911                                            ss.subSet(fromElement, toElement));
2912         }
2913     }
2914
2915     public SortedSet tailSet(Object fromElement)
2916     {
2917       synchronized (mutex)
2918         {
2919           return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement));
2920         }
2921     }
2922   } // class SynchronizedSortedSet
2923
2924 \f
2925   /**
2926    * Returns an unmodifiable view of the given collection. This allows
2927    * "read-only" access, although changes in the backing collection show up
2928    * in this view. Attempts to modify the collection directly or via iterators
2929    * will fail with {@link UnsupportedOperationException}.
2930    * <p>
2931    *
2932    * Since the collection might be a List or a Set, and those have incompatible
2933    * equals and hashCode requirements, this relies on Object's implementation
2934    * rather than passing those calls on to the wrapped collection. The returned
2935    * Collection implements Serializable, but can only be serialized if
2936    * the collection it wraps is likewise Serializable.
2937    *
2938    * @param c the collection to wrap
2939    * @return a read-only view of the collection
2940    * @see Serializable
2941    */
2942   public static Collection unmodifiableCollection(Collection c)
2943   {
2944     return new UnmodifiableCollection(c);
2945   }
2946
2947   /**
2948    * The implementation of {@link #unmodifiableCollection(Collection)}. This
2949    * class name is required for compatibility with Sun's JDK serializability.
2950    *
2951    * @author Eric Blake <ebb9@email.byu.edu>
2952    */
2953   private static class UnmodifiableCollection
2954     implements Collection, Serializable
2955   {
2956     /**
2957      * Compatible with JDK 1.4.
2958      */
2959     private static final long serialVersionUID = 1820017752578914078L;
2960
2961     /**
2962      * The wrapped collection. Package visible for use by subclasses.
2963      * @serial the real collection
2964      */
2965     final Collection c;
2966
2967     /**
2968      * Wrap a given collection.
2969      * @param c the collection to wrap
2970      * @throws NullPointerException if c is null
2971      */
2972     UnmodifiableCollection(Collection c)
2973     {
2974       this.c = c;
2975       if (c == null)
2976         throw new NullPointerException();
2977     }
2978
2979     public boolean add(Object o)
2980     {
2981       throw new UnsupportedOperationException();
2982     }
2983
2984     public boolean addAll(Collection c)
2985     {
2986       throw new UnsupportedOperationException();
2987     }
2988
2989     public void clear()
2990     {
2991       throw new UnsupportedOperationException();
2992     }
2993
2994     public boolean contains(Object o)
2995     {
2996       return c.contains(o);
2997     }
2998
2999     public boolean containsAll(Collection c1)
3000     {
3001       return c.containsAll(c1);
3002     }
3003
3004     public boolean isEmpty()
3005     {
3006       return c.isEmpty();
3007     }
3008
3009     public Iterator iterator()
3010     {
3011       return new UnmodifiableIterator(c.iterator());
3012     }
3013
3014     public boolean remove(Object o)
3015     {
3016       throw new UnsupportedOperationException();
3017     }
3018
3019     public boolean removeAll(Collection c)
3020     {
3021       throw new UnsupportedOperationException();
3022     }
3023
3024     public boolean retainAll(Collection c)
3025     {
3026       throw new UnsupportedOperationException();
3027     }
3028
3029     public int size()
3030     {
3031       return c.size();
3032     }
3033
3034     public Object[] toArray()
3035     {
3036       return c.toArray();
3037     }
3038
3039     public Object[] toArray(Object[] a)
3040     {
3041       return c.toArray(a);
3042     }
3043
3044     public String toString()
3045     {
3046       return c.toString();
3047     }
3048   } // class UnmodifiableCollection
3049
3050   /**
3051    * The implementation of the various iterator methods in the
3052    * unmodifiable classes.
3053    *
3054    * @author Eric Blake <ebb9@email.byu.edu>
3055    */
3056   private static class UnmodifiableIterator implements Iterator
3057   {
3058     /**
3059      * The wrapped iterator.
3060      */
3061     private final Iterator i;
3062
3063     /**
3064      * Only trusted code creates a wrapper.
3065      * @param i the wrapped iterator
3066      */
3067     UnmodifiableIterator(Iterator i)
3068     {
3069       this.i = i;
3070     }
3071
3072     public Object next()
3073     {
3074       return i.next();
3075     }
3076
3077     public boolean hasNext()
3078     {
3079       return i.hasNext();
3080     }
3081
3082     public void remove()
3083     {
3084       throw new UnsupportedOperationException();
3085     }
3086   } // class UnmodifiableIterator
3087
3088   /**
3089    * Returns an unmodifiable view of the given list. This allows
3090    * "read-only" access, although changes in the backing list show up
3091    * in this view. Attempts to modify the list directly, via iterators, or
3092    * via sublists, will fail with {@link UnsupportedOperationException}.
3093    * <p>
3094    *
3095    * The returned List implements Serializable, but can only be serialized if
3096    * the list it wraps is likewise Serializable. In addition, if the wrapped
3097    * list implements RandomAccess, this does too.
3098    *
3099    * @param l the list to wrap
3100    * @return a read-only view of the list
3101    * @see Serializable
3102    * @see RandomAccess
3103    */
3104   public static List unmodifiableList(List l)
3105   {
3106     if (l instanceof RandomAccess)
3107       return new UnmodifiableRandomAccessList(l);
3108     return new UnmodifiableList(l);
3109   }
3110
3111   /**
3112    * The implementation of {@link #unmodifiableList(List)} for sequential
3113    * lists. This class name is required for compatibility with Sun's JDK
3114    * serializability.
3115    *
3116    * @author Eric Blake <ebb9@email.byu.edu>
3117    */
3118   private static class UnmodifiableList extends UnmodifiableCollection
3119     implements List
3120   {
3121     /**
3122      * Compatible with JDK 1.4.
3123      */
3124     private static final long serialVersionUID = -283967356065247728L;
3125
3126
3127     /**
3128      * The wrapped list; stored both here and in the superclass to avoid
3129      * excessive casting. Package visible for use by subclass.
3130      * @serial the wrapped list
3131      */
3132     final List list;
3133
3134     /**
3135      * Wrap a given list.
3136      * @param l the list to wrap
3137      * @throws NullPointerException if l is null
3138      */
3139     UnmodifiableList(List l)
3140     {
3141       super(l);
3142       list = l;
3143     }
3144
3145     public void add(int index, Object o)
3146     {
3147       throw new UnsupportedOperationException();
3148     }
3149
3150     public boolean addAll(int index, Collection c)
3151     {
3152       throw new UnsupportedOperationException();
3153     }
3154
3155     public boolean equals(Object o)
3156     {
3157       return list.equals(o);
3158     }
3159
3160     public Object get(int index)
3161     {
3162       return list.get(index);
3163     }
3164
3165     public int hashCode()
3166     {
3167       return list.hashCode();
3168     }
3169
3170     public int indexOf(Object o)
3171     {
3172       return list.indexOf(o);
3173     }
3174
3175     public int lastIndexOf(Object o)
3176     {
3177       return list.lastIndexOf(o);
3178     }
3179
3180     public ListIterator listIterator()
3181     {
3182       return new UnmodifiableListIterator(list.listIterator());
3183     }
3184
3185     public ListIterator listIterator(int index)
3186     {
3187       return new UnmodifiableListIterator(list.listIterator(index));
3188     }
3189
3190     public Object remove(int index)
3191     {
3192       throw new UnsupportedOperationException();
3193     }
3194
3195     public Object set(int index, Object o)
3196     {
3197       throw new UnsupportedOperationException();
3198     }
3199
3200     public List subList(int fromIndex, int toIndex)
3201     {
3202       return unmodifiableList(list.subList(fromIndex, toIndex));
3203     }
3204   } // class UnmodifiableList
3205
3206   /**
3207    * The implementation of {@link #unmodifiableList(List)} for random-access
3208    * lists. This class name is required for compatibility with Sun's JDK
3209    * serializability.
3210    *
3211    * @author Eric Blake <ebb9@email.byu.edu>
3212    */
3213   private static final class UnmodifiableRandomAccessList
3214     extends UnmodifiableList implements RandomAccess
3215   {
3216     /**
3217      * Compatible with JDK 1.4.
3218      */
3219     private static final long serialVersionUID = -2542308836966382001L;
3220
3221     /**
3222      * Wrap a given list.
3223      * @param l the list to wrap
3224      * @throws NullPointerException if l is null
3225      */
3226     UnmodifiableRandomAccessList(List l)
3227     {
3228       super(l);
3229     }
3230   } // class UnmodifiableRandomAccessList
3231
3232   /**
3233    * The implementation of {@link UnmodifiableList#listIterator()}.
3234    *
3235    * @author Eric Blake <ebb9@email.byu.edu>
3236    */
3237   private static final class UnmodifiableListIterator
3238     extends UnmodifiableIterator implements ListIterator
3239   {
3240     /**
3241      * The wrapped iterator, stored both here and in the superclass to
3242      * avoid excessive casting.
3243      */
3244     private final ListIterator li;
3245
3246     /**
3247      * Only trusted code creates a wrapper.
3248      * @param li the wrapped iterator
3249      */
3250     UnmodifiableListIterator(ListIterator li)
3251     {
3252       super(li);
3253       this.li = li;
3254     }
3255
3256     public void add(Object o)
3257     {
3258       throw new UnsupportedOperationException();
3259     }
3260
3261     public boolean hasPrevious()
3262     {
3263       return li.hasPrevious();
3264     }
3265
3266     public int nextIndex()
3267     {
3268       return li.nextIndex();
3269     }
3270
3271     public Object previous()
3272     {
3273       return li.previous();
3274     }
3275
3276     public int previousIndex()
3277     {
3278       return li.previousIndex();
3279     }
3280
3281     public void set(Object o)
3282     {
3283       throw new UnsupportedOperationException();
3284     }
3285   } // class UnmodifiableListIterator
3286
3287   /**
3288    * Returns an unmodifiable view of the given map. This allows "read-only"
3289    * access, although changes in the backing map show up in this view.
3290    * Attempts to modify the map directly, or via collection views or their
3291    * iterators will fail with {@link UnsupportedOperationException}.
3292    * <p>
3293    *
3294    * The returned Map implements Serializable, but can only be serialized if
3295    * the map it wraps is likewise Serializable.
3296    *
3297    * @param m the map to wrap
3298    * @return a read-only view of the map
3299    * @see Serializable
3300    */
3301   public static Map unmodifiableMap(Map m)
3302   {
3303     return new UnmodifiableMap(m);
3304   }
3305
3306   /**
3307    * The implementation of {@link #unmodifiableMap(Map)}. This
3308    * class name is required for compatibility with Sun's JDK serializability.
3309    *
3310    * @author Eric Blake <ebb9@email.byu.edu>
3311    */
3312   private static class UnmodifiableMap implements Map, Serializable
3313   {
3314     /**
3315      * Compatible with JDK 1.4.
3316      */
3317     private static final long serialVersionUID = -1034234728574286014L;
3318
3319     /**
3320      * The wrapped map.
3321      * @serial the real map
3322      */
3323     private final Map m;
3324
3325     /**
3326      * Cache the entry set.
3327      */
3328     private transient Set entries;
3329
3330     /**
3331      * Cache the key set.
3332      */
3333     private transient Set keys;
3334
3335     /**
3336      * Cache the value collection.
3337      */
3338     private transient Collection values;
3339
3340     /**
3341      * Wrap a given map.
3342      * @param m the map to wrap
3343      * @throws NullPointerException if m is null
3344      */
3345     UnmodifiableMap(Map m)
3346     {
3347       this.m = m;
3348       if (m == null)
3349         throw new NullPointerException();
3350     }
3351
3352     public void clear()
3353     {
3354       throw new UnsupportedOperationException();
3355     }
3356
3357     public boolean containsKey(Object key)
3358     {
3359       return m.containsKey(key);
3360     }
3361
3362     public boolean containsValue(Object value)
3363     {
3364       return m.containsValue(value);
3365     }
3366
3367     public Set entrySet()
3368     {
3369       if (entries == null)
3370         entries = new UnmodifiableEntrySet(m.entrySet());
3371       return entries;
3372     }
3373
3374     /**
3375      * The implementation of {@link UnmodifiableMap#entrySet()}. This class
3376      * name is required for compatibility with Sun's JDK serializability.
3377      *
3378      * @author Eric Blake <ebb9@email.byu.edu>
3379      */
3380     private static final class UnmodifiableEntrySet extends UnmodifiableSet
3381       implements Serializable
3382     {
3383       /**
3384        * Compatible with JDK 1.4.
3385        */
3386       private static final long serialVersionUID = 7854390611657943733L;
3387
3388       /**
3389        * Wrap a given set.
3390        * @param s the set to wrap
3391        */
3392       UnmodifiableEntrySet(Set s)
3393       {
3394         super(s);
3395       }
3396
3397       // The iterator must return unmodifiable map entries.
3398       public Iterator iterator()
3399       {
3400         return new UnmodifiableIterator(c.iterator())
3401         {
3402           public Object next()
3403           {
3404             final Map.Entry e = (Map.Entry) super.next();
3405             return new Map.Entry()
3406             {
3407               public boolean equals(Object o)
3408               {
3409                 return e.equals(o);
3410               }
3411               public Object getKey()
3412               {
3413                 return e.getKey();
3414               }
3415               public Object getValue()
3416               {
3417                 return e.getValue();
3418               }
3419               public int hashCode()
3420               {
3421                 return e.hashCode();
3422               }
3423               public Object setValue(Object value)
3424               {
3425                 throw new UnsupportedOperationException();
3426               }
3427               public String toString()
3428               {
3429                 return e.toString();
3430               }
3431             };
3432           }
3433         };
3434       }
3435     } // class UnmodifiableEntrySet
3436
3437     public boolean equals(Object o)
3438     {
3439       return m.equals(o);
3440     }
3441
3442     public Object get(Object key)
3443     {
3444       return m.get(key);
3445     }
3446
3447     public Object put(Object key, Object value)
3448     {
3449       throw new UnsupportedOperationException();
3450     }
3451
3452     public int hashCode()
3453     {
3454       return m.hashCode();
3455     }
3456
3457     public boolean isEmpty()
3458     {
3459       return m.isEmpty();
3460     }
3461
3462     public Set keySet()
3463     {
3464       if (keys == null)
3465         keys = new UnmodifiableSet(m.keySet());
3466       return keys;
3467     }
3468
3469     public void putAll(Map m)
3470     {
3471       throw new UnsupportedOperationException();
3472     }
3473
3474     public Object remove(Object o)
3475     {
3476       throw new UnsupportedOperationException();
3477     }
3478
3479     public int size()
3480     {
3481       return m.size();
3482     }
3483
3484     public String toString()
3485     {
3486       return m.toString();
3487     }
3488
3489     public Collection values()
3490     {
3491       if (values == null)
3492         values = new UnmodifiableCollection(m.values());
3493       return values;
3494     }
3495   } // class UnmodifiableMap
3496
3497   /**
3498    * Returns an unmodifiable view of the given set. This allows
3499    * "read-only" access, although changes in the backing set show up
3500    * in this view. Attempts to modify the set directly or via iterators
3501    * will fail with {@link UnsupportedOperationException}.
3502    * <p>
3503    *
3504    * The returned Set implements Serializable, but can only be serialized if
3505    * the set it wraps is likewise Serializable.
3506    *
3507    * @param s the set to wrap
3508    * @return a read-only view of the set
3509    * @see Serializable
3510    */
3511   public static Set unmodifiableSet(Set s)
3512   {
3513     return new UnmodifiableSet(s);
3514   }
3515
3516   /**
3517    * The implementation of {@link #unmodifiableSet(Set)}. This class
3518    * name is required for compatibility with Sun's JDK serializability.
3519    *
3520    * @author Eric Blake <ebb9@email.byu.edu>
3521    */
3522   private static class UnmodifiableSet extends UnmodifiableCollection
3523     implements Set
3524   {
3525     /**
3526      * Compatible with JDK 1.4.
3527      */
3528     private static final long serialVersionUID = -9215047833775013803L;
3529
3530     /**
3531      * Wrap a given set.
3532      * @param s the set to wrap
3533      * @throws NullPointerException if s is null
3534      */
3535     UnmodifiableSet(Set s)
3536     {
3537       super(s);
3538     }
3539
3540     public boolean equals(Object o)
3541     {
3542       return c.equals(o);
3543     }
3544
3545     public int hashCode()
3546     {
3547       return c.hashCode();
3548     }
3549   } // class UnmodifiableSet
3550
3551   /**
3552    * Returns an unmodifiable view of the given sorted map. This allows
3553    * "read-only" access, although changes in the backing map show up in this
3554    * view. Attempts to modify the map directly, via subviews, via collection
3555    * views, or iterators, will fail with {@link UnsupportedOperationException}.
3556    * <p>
3557    *
3558    * The returned SortedMap implements Serializable, but can only be
3559    * serialized if the map it wraps is likewise Serializable.
3560    *
3561    * @param m the map to wrap
3562    * @return a read-only view of the map
3563    * @see Serializable
3564    */
3565   public static SortedMap unmodifiableSortedMap(SortedMap m)
3566   {
3567     return new UnmodifiableSortedMap(m);
3568   }
3569
3570   /**
3571    * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This
3572    * class name is required for compatibility with Sun's JDK serializability.
3573    *
3574    * @author Eric Blake <ebb9@email.byu.edu>
3575    */
3576   private static class UnmodifiableSortedMap extends UnmodifiableMap
3577     implements SortedMap
3578   {
3579     /**
3580      * Compatible with JDK 1.4.
3581      */
3582     private static final long serialVersionUID = -8806743815996713206L;
3583
3584     /**
3585      * The wrapped map; stored both here and in the superclass to avoid
3586      * excessive casting.
3587      * @serial the wrapped map
3588      */
3589     private final SortedMap sm;
3590
3591     /**
3592      * Wrap a given map.
3593      * @param sm the map to wrap
3594      * @throws NullPointerException if sm is null
3595      */
3596     UnmodifiableSortedMap(SortedMap sm)
3597     {
3598       super(sm);
3599       this.sm = sm;
3600     }
3601
3602     public Comparator comparator()
3603     {
3604       return sm.comparator();
3605     }
3606
3607     public Object firstKey()
3608     {
3609       return sm.firstKey();
3610     }
3611
3612     public SortedMap headMap(Object toKey)
3613     {
3614       return new UnmodifiableSortedMap(sm.headMap(toKey));
3615     }
3616
3617     public Object lastKey()
3618     {
3619       return sm.lastKey();
3620     }
3621
3622     public SortedMap subMap(Object fromKey, Object toKey)
3623     {
3624       return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey));
3625     }
3626
3627     public SortedMap tailMap(Object fromKey)
3628     {
3629       return new UnmodifiableSortedMap(sm.tailMap(fromKey));
3630     }
3631   } // class UnmodifiableSortedMap
3632
3633   /**
3634    * Returns an unmodifiable view of the given sorted set. This allows
3635    * "read-only" access, although changes in the backing set show up
3636    * in this view. Attempts to modify the set directly, via subsets, or via
3637    * iterators, will fail with {@link UnsupportedOperationException}.
3638    * <p>
3639    *
3640    * The returns SortedSet implements Serializable, but can only be
3641    * serialized if the set it wraps is likewise Serializable.
3642    *
3643    * @param s the set to wrap
3644    * @return a read-only view of the set
3645    * @see Serializable
3646    */
3647   public static SortedSet unmodifiableSortedSet(SortedSet s)
3648   {
3649     return new UnmodifiableSortedSet(s);
3650   }
3651
3652   /**
3653    * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This
3654    * class name is required for compatibility with Sun's JDK serializability.
3655    *
3656    * @author Eric Blake <ebb9@email.byu.edu>
3657    */
3658   private static class UnmodifiableSortedSet extends UnmodifiableSet
3659     implements SortedSet
3660   {
3661     /**
3662      * Compatible with JDK 1.4.
3663      */
3664     private static final long serialVersionUID = -4929149591599911165L;
3665
3666     /**
3667      * The wrapped set; stored both here and in the superclass to avoid
3668      * excessive casting.
3669      * @serial the wrapped set
3670      */
3671     private SortedSet ss;
3672
3673     /**
3674      * Wrap a given set.
3675      * @param ss the set to wrap
3676      * @throws NullPointerException if ss is null
3677      */
3678     UnmodifiableSortedSet(SortedSet ss)
3679     {
3680       super(ss);
3681       this.ss = ss;
3682     }
3683
3684     public Comparator comparator()
3685     {
3686       return ss.comparator();
3687     }
3688
3689     public Object first()
3690     {
3691       return ss.first();
3692     }
3693
3694     public SortedSet headSet(Object toElement)
3695     {
3696       return new UnmodifiableSortedSet(ss.headSet(toElement));
3697     }
3698
3699     public Object last()
3700     {
3701       return ss.last();
3702     }
3703
3704     public SortedSet subSet(Object fromElement, Object toElement)
3705     {
3706       return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement));
3707     }
3708
3709     public SortedSet tailSet(Object fromElement)
3710     {
3711       return new UnmodifiableSortedSet(ss.tailSet(fromElement));
3712     }
3713   } // class UnmodifiableSortedSet
3714 } // class Collections