1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.util;
19 
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.io.ObjectStreamException;
24 import java.io.Serializable;
25 import java.lang.reflect.Array;
26 
27 /**
28  * {@code Collections} contains static methods which operate on
29  * {@code Collection} classes.
30  *
31  * @since 1.2
32  */
33 public class Collections {
34 
35     private static final Iterator<?> EMPTY_ITERATOR = new Iterator<Object>() {
36         @Override public boolean hasNext() {
37             return false;
38         }
39 
40         @Override public Object next() {
41             throw new NoSuchElementException();
42         }
43 
44         @Override public void remove() {
45             throw new IllegalStateException();
46         }
47     };
48 
49     private static final Enumeration<?> EMPTY_ENUMERATION = new Enumeration<Object>() {
50         @Override public boolean hasMoreElements() {
51             return false;
52         }
53 
54         @Override public Object nextElement() {
55             throw new NoSuchElementException();
56         }
57     };
58 
59     private static final class CopiesList<E> extends AbstractList<E> implements Serializable {
60         private static final long serialVersionUID = 2739099268398711800L;
61         private final int n;
62         private final E element;
63 
CopiesList(int length, E object)64         CopiesList(int length, E object) {
65             if (length < 0) {
66                 throw new IllegalArgumentException("length < 0: " + length);
67             }
68             n = length;
69             element = object;
70         }
71 
contains(Object object)72         @Override public boolean contains(Object object) {
73             return element == null ? object == null : element.equals(object);
74         }
75 
size()76         @Override public int size() {
77             return n;
78         }
79 
get(int location)80         @Override public E get(int location) {
81             if (location >= 0 && location < n) {
82                 return element;
83             }
84             throw new IndexOutOfBoundsException();
85         }
86     }
87 
88     @SuppressWarnings("unchecked")
89     private static final class EmptyList extends AbstractList
90             implements RandomAccess, Serializable {
91         private static final long serialVersionUID = 8842843931221139166L;
92 
contains(Object object)93         @Override public boolean contains(Object object) {
94             return false;
95         }
96 
size()97         @Override public int size() {
98             return 0;
99         }
100 
get(int location)101         @Override public Object get(int location) {
102             throw new IndexOutOfBoundsException();
103         }
104 
readResolve()105         private Object readResolve() {
106             return Collections.EMPTY_LIST;
107         }
108     }
109 
110     @SuppressWarnings("unchecked")
111     private static final class EmptySet extends AbstractSet implements Serializable {
112         private static final long serialVersionUID = 1582296315990362920L;
113 
contains(Object object)114         @Override public boolean contains(Object object) {
115             return false;
116         }
117 
size()118         @Override public int size() {
119             return 0;
120         }
121 
iterator()122         @Override public Iterator iterator() {
123             return EMPTY_ITERATOR;
124         }
125 
readResolve()126         private Object readResolve() {
127             return Collections.EMPTY_SET;
128         }
129     }
130 
131     @SuppressWarnings("unchecked")
132     private static final class EmptyMap extends AbstractMap implements Serializable {
133         private static final long serialVersionUID = 6428348081105594320L;
134 
containsKey(Object key)135         @Override public boolean containsKey(Object key) {
136             return false;
137         }
138 
containsValue(Object value)139         @Override public boolean containsValue(Object value) {
140             return false;
141         }
142 
entrySet()143         @Override public Set entrySet() {
144             return EMPTY_SET;
145         }
146 
get(Object key)147         @Override public Object get(Object key) {
148             return null;
149         }
150 
keySet()151         @Override public Set keySet() {
152             return EMPTY_SET;
153         }
154 
values()155         @Override public Collection values() {
156             return EMPTY_LIST;
157         }
158 
readResolve()159         private Object readResolve() {
160             return Collections.EMPTY_MAP;
161         }
162     }
163 
164     /**
165      * An empty immutable instance of {@link List}.
166      */
167     @SuppressWarnings("unchecked")
168     public static final List EMPTY_LIST = new EmptyList();
169 
170     /**
171      * An empty immutable instance of {@link Set}.
172      */
173     @SuppressWarnings("unchecked")
174     public static final Set EMPTY_SET = new EmptySet();
175 
176     /**
177      * An empty immutable instance of {@link Map}.
178      */
179     @SuppressWarnings("unchecked")
180     public static final Map EMPTY_MAP = new EmptyMap();
181 
182     /**
183      * This class is a singleton so that equals() and hashCode() work properly.
184      */
185     private static final class ReverseComparator<T> implements Comparator<T>, Serializable {
186         private static final ReverseComparator<Object> INSTANCE = new ReverseComparator<Object>();
187 
188         private static final long serialVersionUID = 7207038068494060240L;
189 
190         @SuppressWarnings("unchecked")
compare(T o1, T o2)191         @Override public int compare(T o1, T o2) {
192             Comparable<T> c2 = (Comparable<T>) o2;
193             return c2.compareTo(o1);
194         }
195 
readResolve()196         private Object readResolve() throws ObjectStreamException {
197             return INSTANCE;
198         }
199     }
200 
201     private static final class ReverseComparator2<T> implements Comparator<T>, Serializable {
202         private static final long serialVersionUID = 4374092139857L;
203         private final Comparator<T> cmp;
204 
ReverseComparator2(Comparator<T> comparator)205         ReverseComparator2(Comparator<T> comparator) {
206             this.cmp = comparator;
207         }
208 
compare(T o1, T o2)209         @Override public int compare(T o1, T o2) {
210             return cmp.compare(o2, o1);
211         }
212 
equals(Object o)213         @Override public boolean equals(Object o) {
214             return o instanceof ReverseComparator2
215                     && ((ReverseComparator2) o).cmp.equals(cmp);
216         }
217 
hashCode()218         @Override public int hashCode() {
219             return ~cmp.hashCode();
220         }
221     }
222 
223     private static final class SingletonSet<E> extends AbstractSet<E> implements Serializable {
224         private static final long serialVersionUID = 3193687207550431679L;
225         final E element;
226 
SingletonSet(E object)227         SingletonSet(E object) {
228             element = object;
229         }
230 
contains(Object object)231         @Override public boolean contains(Object object) {
232             return element == null ? object == null : element.equals(object);
233         }
234 
size()235         @Override public int size() {
236             return 1;
237         }
238 
iterator()239         @Override public Iterator<E> iterator() {
240             return new Iterator<E>() {
241                 boolean hasNext = true;
242 
243                 @Override public boolean hasNext() {
244                     return hasNext;
245                 }
246 
247                 @Override public E next() {
248                     if (hasNext) {
249                         hasNext = false;
250                         return element;
251                     }
252                     throw new NoSuchElementException();
253                 }
254 
255                 @Override public void remove() {
256                     throw new UnsupportedOperationException();
257                 }
258             };
259         }
260     }
261 
262     private static final class SingletonList<E> extends AbstractList<E> implements Serializable {
263         private static final long serialVersionUID = 3093736618740652951L;
264 
265         final E element;
266 
SingletonList(E object)267         SingletonList(E object) {
268             element = object;
269         }
270 
contains(Object object)271         @Override public boolean contains(Object object) {
272             return element == null ? object == null : element.equals(object);
273         }
274 
get(int location)275         @Override public E get(int location) {
276             if (location == 0) {
277                 return element;
278             }
279             throw new IndexOutOfBoundsException();
280         }
281 
size()282         @Override public int size() {
283             return 1;
284         }
285     }
286 
287     private static final class SingletonMap<K, V> extends AbstractMap<K, V>
288             implements Serializable {
289         private static final long serialVersionUID = -6979724477215052911L;
290 
291         final K k;
292         final V v;
293 
SingletonMap(K key, V value)294         SingletonMap(K key, V value) {
295             k = key;
296             v = value;
297         }
298 
containsKey(Object key)299         @Override public boolean containsKey(Object key) {
300             return k == null ? key == null : k.equals(key);
301         }
302 
containsValue(Object value)303         @Override public boolean containsValue(Object value) {
304             return v == null ? value == null : v.equals(value);
305         }
306 
get(Object key)307         @Override public V get(Object key) {
308             if (containsKey(key)) {
309                 return v;
310             }
311             return null;
312         }
313 
size()314         @Override public int size() {
315             return 1;
316         }
317 
entrySet()318         @Override public Set<Map.Entry<K, V>> entrySet() {
319             return new AbstractSet<Map.Entry<K, V>>() {
320                 @Override public boolean contains(Object object) {
321                     if (object instanceof Map.Entry) {
322                         Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
323                         return containsKey(entry.getKey())
324                                 && containsValue(entry.getValue());
325                     }
326                     return false;
327                 }
328 
329                 @Override public int size() {
330                     return 1;
331                 }
332 
333                 @Override public Iterator<Map.Entry<K, V>> iterator() {
334                     return new Iterator<Map.Entry<K, V>>() {
335                         boolean hasNext = true;
336 
337                         @Override public boolean hasNext() {
338                             return hasNext;
339                         }
340 
341                         @Override public Map.Entry<K, V> next() {
342                             if (!hasNext) {
343                                 throw new NoSuchElementException();
344                             }
345 
346                             hasNext = false;
347                             return new MapEntry<K, V>(k, v) {
348                                 @Override public V setValue(V value) {
349                                     throw new UnsupportedOperationException();
350                                 }
351                             };
352                         }
353 
354                         @Override public void remove() {
355                             throw new UnsupportedOperationException();
356                         }
357                     };
358                 }
359             };
360         }
361     }
362 
363     static class SynchronizedCollection<E> implements Collection<E>, Serializable {
364         private static final long serialVersionUID = 3053995032091335093L;
365         final Collection<E> c;
366         final Object mutex;
367 
368         SynchronizedCollection(Collection<E> collection) {
369             c = collection;
370             mutex = this;
371         }
372 
373         SynchronizedCollection(Collection<E> collection, Object mutex) {
374             c = collection;
375             this.mutex = mutex;
376         }
377 
378         @Override public boolean add(E object) {
379             synchronized (mutex) {
380                 return c.add(object);
381             }
382         }
383 
384         @Override public boolean addAll(Collection<? extends E> collection) {
385             synchronized (mutex) {
386                 return c.addAll(collection);
387             }
388         }
389 
390         @Override public void clear() {
391             synchronized (mutex) {
392                 c.clear();
393             }
394         }
395 
396         @Override public boolean contains(Object object) {
397             synchronized (mutex) {
398                 return c.contains(object);
399             }
400         }
401 
402         @Override public boolean containsAll(Collection<?> collection) {
403             synchronized (mutex) {
404                 return c.containsAll(collection);
405             }
406         }
407 
408         @Override public boolean isEmpty() {
409             synchronized (mutex) {
410                 return c.isEmpty();
411             }
412         }
413 
414         @Override public Iterator<E> iterator() {
415             synchronized (mutex) {
416                 return c.iterator();
417             }
418         }
419 
420         @Override public boolean remove(Object object) {
421             synchronized (mutex) {
422                 return c.remove(object);
423             }
424         }
425 
426         @Override public boolean removeAll(Collection<?> collection) {
427             synchronized (mutex) {
428                 return c.removeAll(collection);
429             }
430         }
431 
432         @Override public boolean retainAll(Collection<?> collection) {
433             synchronized (mutex) {
434                 return c.retainAll(collection);
435             }
436         }
437 
438         @Override public int size() {
439             synchronized (mutex) {
440                 return c.size();
441             }
442         }
443 
444         @Override public java.lang.Object[] toArray() {
445             synchronized (mutex) {
446                 return c.toArray();
447             }
448         }
449 
450         @Override public String toString() {
451             synchronized (mutex) {
452                 return c.toString();
453             }
454         }
455 
456         @Override public <T> T[] toArray(T[] array) {
457             synchronized (mutex) {
458                 return c.toArray(array);
459             }
460         }
461 
462         private void writeObject(ObjectOutputStream stream) throws IOException {
463             synchronized (mutex) {
464                 stream.defaultWriteObject();
465             }
466         }
467     }
468 
469     static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>
470             implements RandomAccess {
471         private static final long serialVersionUID = 1530674583602358482L;
472 
473         SynchronizedRandomAccessList(List<E> l) {
474             super(l);
475         }
476 
477         SynchronizedRandomAccessList(List<E> l, Object mutex) {
478             super(l, mutex);
479         }
480 
481         @Override public List<E> subList(int start, int end) {
482             synchronized (mutex) {
483                 return new SynchronizedRandomAccessList<E>(list.subList(start, end), mutex);
484             }
485         }
486 
487         /**
488          * Replaces this SynchronizedRandomAccessList with a SynchronizedList so
489          * that JREs before 1.4 can deserialize this object without any
490          * problems. This is necessary since RandomAccess API was introduced
491          * only in 1.4.
492          * <p>
493          *
494          * @return SynchronizedList
495          *
496          * @see SynchronizedList#readResolve()
497          */
498         private Object writeReplace() {
499             return new SynchronizedList<E>(list);
500         }
501     }
502 
503     static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {
504         private static final long serialVersionUID = -7754090372962971524L;
505         final List<E> list;
506 
507         SynchronizedList(List<E> l) {
508             super(l);
509             list = l;
510         }
511 
512         SynchronizedList(List<E> l, Object mutex) {
513             super(l, mutex);
514             list = l;
515         }
516 
517         @Override public void add(int location, E object) {
518             synchronized (mutex) {
519                 list.add(location, object);
520             }
521         }
522 
523         @Override public boolean addAll(int location, Collection<? extends E> collection) {
524             synchronized (mutex) {
525                 return list.addAll(location, collection);
526             }
527         }
528 
529         @Override public boolean equals(Object object) {
530             synchronized (mutex) {
531                 return list.equals(object);
532             }
533         }
534 
535         @Override public E get(int location) {
536             synchronized (mutex) {
537                 return list.get(location);
538             }
539         }
540 
541         @Override public int hashCode() {
542             synchronized (mutex) {
543                 return list.hashCode();
544             }
545         }
546 
547         @Override public int indexOf(Object object) {
548             final int size;
549             final Object[] array;
550             synchronized (mutex) {
551                 size = list.size();
552                 array = new Object[size];
553                 list.toArray(array);
554             }
555             if (object != null) {
556                 for (int i = 0; i < size; i++) {
557                     if (object.equals(array[i])) {
558                         return i;
559                     }
560                 }
561             } else {
562                 for (int i = 0; i < size; i++) {
563                     if (array[i] == null) {
564                         return i;
565                     }
566                 }
567             }
568             return -1;
569         }
570 
571         @Override public int lastIndexOf(Object object) {
572             final int size;
573             final Object[] array;
574             synchronized (mutex) {
575                 size = list.size();
576                 array = new Object[size];
577                 list.toArray(array);
578             }
579             if (object != null) {
580                 for (int i = size - 1; i >= 0; i--) {
581                     if (object.equals(array[i])) {
582                         return i;
583                     }
584                 }
585             } else {
586                 for (int i = size - 1; i >= 0; i--) {
587                     if (array[i] == null) {
588                         return i;
589                     }
590                 }
591             }
592             return -1;
593         }
594 
595         @Override public ListIterator<E> listIterator() {
596             synchronized (mutex) {
597                 return list.listIterator();
598             }
599         }
600 
601         @Override public ListIterator<E> listIterator(int location) {
602             synchronized (mutex) {
603                 return list.listIterator(location);
604             }
605         }
606 
607         @Override public E remove(int location) {
608             synchronized (mutex) {
609                 return list.remove(location);
610             }
611         }
612 
613         @Override public E set(int location, E object) {
614             synchronized (mutex) {
615                 return list.set(location, object);
616             }
617         }
618 
619         @Override public List<E> subList(int start, int end) {
620             synchronized (mutex) {
621                 return new SynchronizedList<E>(list.subList(start, end), mutex);
622             }
623         }
624 
625         private void writeObject(ObjectOutputStream stream) throws IOException {
626             synchronized (mutex) {
627                 stream.defaultWriteObject();
628             }
629         }
630 
631         /**
632          * Resolves SynchronizedList instances to SynchronizedRandomAccessList
633          * instances if the underlying list is a Random Access list.
634          * <p>
635          * This is necessary since SynchronizedRandomAccessList instances are
636          * replaced with SynchronizedList instances during serialization for
637          * compliance with JREs before 1.4.
638          * <p>
639          *
640          * @return a SynchronizedList instance if the underlying list implements
641          *         RandomAccess interface, or this same object if not.
642          *
643          * @see SynchronizedRandomAccessList#writeReplace()
644          */
645         private Object readResolve() {
646             if (list instanceof RandomAccess) {
647                 return new SynchronizedRandomAccessList<E>(list, mutex);
648             }
649             return this;
650         }
651     }
652 
653     static class SynchronizedMap<K, V> implements Map<K, V>, Serializable {
654         private static final long serialVersionUID = 1978198479659022715L;
655 
656         private final Map<K, V> m;
657 
658         final Object mutex;
659 
660         SynchronizedMap(Map<K, V> map) {
661             m = map;
662             mutex = this;
663         }
664 
665         SynchronizedMap(Map<K, V> map, Object mutex) {
666             m = map;
667             this.mutex = mutex;
668         }
669 
670         @Override public void clear() {
671             synchronized (mutex) {
672                 m.clear();
673             }
674         }
675 
676         @Override public boolean containsKey(Object key) {
677             synchronized (mutex) {
678                 return m.containsKey(key);
679             }
680         }
681 
682         @Override public boolean containsValue(Object value) {
683             synchronized (mutex) {
684                 return m.containsValue(value);
685             }
686         }
687 
688         @Override public Set<Map.Entry<K, V>> entrySet() {
689             synchronized (mutex) {
690                 return new SynchronizedSet<Map.Entry<K, V>>(m.entrySet(), mutex);
691             }
692         }
693 
694         @Override public boolean equals(Object object) {
695             synchronized (mutex) {
696                 return m.equals(object);
697             }
698         }
699 
700         @Override public V get(Object key) {
701             synchronized (mutex) {
702                 return m.get(key);
703             }
704         }
705 
706         @Override public int hashCode() {
707             synchronized (mutex) {
708                 return m.hashCode();
709             }
710         }
711 
712         @Override public boolean isEmpty() {
713             synchronized (mutex) {
714                 return m.isEmpty();
715             }
716         }
717 
718         @Override public Set<K> keySet() {
719             synchronized (mutex) {
720                 return new SynchronizedSet<K>(m.keySet(), mutex);
721             }
722         }
723 
724         @Override public V put(K key, V value) {
725             synchronized (mutex) {
726                 return m.put(key, value);
727             }
728         }
729 
730         @Override public void putAll(Map<? extends K, ? extends V> map) {
731             synchronized (mutex) {
732                 m.putAll(map);
733             }
734         }
735 
736         @Override public V remove(Object key) {
737             synchronized (mutex) {
738                 return m.remove(key);
739             }
740         }
741 
742         @Override public int size() {
743             synchronized (mutex) {
744                 return m.size();
745             }
746         }
747 
748         @Override public Collection<V> values() {
749             synchronized (mutex) {
750                 return new SynchronizedCollection<V>(m.values(), mutex);
751             }
752         }
753 
754         @Override public String toString() {
755             synchronized (mutex) {
756                 return m.toString();
757             }
758         }
759 
760         private void writeObject(ObjectOutputStream stream) throws IOException {
761             synchronized (mutex) {
762                 stream.defaultWriteObject();
763             }
764         }
765     }
766 
767     static class SynchronizedSet<E> extends SynchronizedCollection<E> implements Set<E> {
768         private static final long serialVersionUID = 487447009682186044L;
769 
770         SynchronizedSet(Set<E> set) {
771             super(set);
772         }
773 
774         SynchronizedSet(Set<E> set, Object mutex) {
775             super(set, mutex);
776         }
777 
778         @Override public boolean equals(Object object) {
779             synchronized (mutex) {
780                 return c.equals(object);
781             }
782         }
783 
784         @Override public int hashCode() {
785             synchronized (mutex) {
786                 return c.hashCode();
787             }
788         }
789 
790         private void writeObject(ObjectOutputStream stream) throws IOException {
791             synchronized (mutex) {
792                 stream.defaultWriteObject();
793             }
794         }
795     }
796 
797     static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V>
798             implements SortedMap<K, V> {
799         private static final long serialVersionUID = -8798146769416483793L;
800 
801         private final SortedMap<K, V> sm;
802 
803         SynchronizedSortedMap(SortedMap<K, V> map) {
804             super(map);
805             sm = map;
806         }
807 
808         SynchronizedSortedMap(SortedMap<K, V> map, Object mutex) {
809             super(map, mutex);
810             sm = map;
811         }
812 
813         @Override public Comparator<? super K> comparator() {
814             synchronized (mutex) {
815                 return sm.comparator();
816             }
817         }
818 
819         @Override public K firstKey() {
820             synchronized (mutex) {
821                 return sm.firstKey();
822             }
823         }
824 
825         @Override public SortedMap<K, V> headMap(K endKey) {
826             synchronized (mutex) {
827                 return new SynchronizedSortedMap<K, V>(sm.headMap(endKey),
828                         mutex);
829             }
830         }
831 
832         @Override public K lastKey() {
833             synchronized (mutex) {
834                 return sm.lastKey();
835             }
836         }
837 
838         @Override public SortedMap<K, V> subMap(K startKey, K endKey) {
839             synchronized (mutex) {
840                 return new SynchronizedSortedMap<K, V>(sm.subMap(startKey,
841                         endKey), mutex);
842             }
843         }
844 
845         @Override public SortedMap<K, V> tailMap(K startKey) {
846             synchronized (mutex) {
847                 return new SynchronizedSortedMap<K, V>(sm.tailMap(startKey),
848                         mutex);
849             }
850         }
851 
852         private void writeObject(ObjectOutputStream stream) throws IOException {
853             synchronized (mutex) {
854                 stream.defaultWriteObject();
855             }
856         }
857     }
858 
859     static class SynchronizedSortedSet<E> extends SynchronizedSet<E> implements SortedSet<E> {
860         private static final long serialVersionUID = 8695801310862127406L;
861 
862         private final SortedSet<E> ss;
863 
864         SynchronizedSortedSet(SortedSet<E> set) {
865             super(set);
866             ss = set;
867         }
868 
869         SynchronizedSortedSet(SortedSet<E> set, Object mutex) {
870             super(set, mutex);
871             ss = set;
872         }
873 
874         @Override public Comparator<? super E> comparator() {
875             synchronized (mutex) {
876                 return ss.comparator();
877             }
878         }
879 
880         @Override public E first() {
881             synchronized (mutex) {
882                 return ss.first();
883             }
884         }
885 
886         @Override public SortedSet<E> headSet(E end) {
887             synchronized (mutex) {
888                 return new SynchronizedSortedSet<E>(ss.headSet(end), mutex);
889             }
890         }
891 
892         @Override public E last() {
893             synchronized (mutex) {
894                 return ss.last();
895             }
896         }
897 
898         @Override public SortedSet<E> subSet(E start, E end) {
899             synchronized (mutex) {
900                 return new SynchronizedSortedSet<E>(ss.subSet(start, end),
901                         mutex);
902             }
903         }
904 
905         @Override public SortedSet<E> tailSet(E start) {
906             synchronized (mutex) {
907                 return new SynchronizedSortedSet<E>(ss.tailSet(start), mutex);
908             }
909         }
910 
911         private void writeObject(ObjectOutputStream stream) throws IOException {
912             synchronized (mutex) {
913                 stream.defaultWriteObject();
914             }
915         }
916     }
917 
918     private static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
919         private static final long serialVersionUID = 1820017752578914078L;
920 
921         final Collection<E> c;
922 
923         UnmodifiableCollection(Collection<E> collection) {
924             c = collection;
925         }
926 
927         @Override public boolean add(E object) {
928             throw new UnsupportedOperationException();
929         }
930 
931         @Override public boolean addAll(Collection<? extends E> collection) {
932             throw new UnsupportedOperationException();
933         }
934 
935         @Override public void clear() {
936             throw new UnsupportedOperationException();
937         }
938 
939         @Override public boolean contains(Object object) {
940             return c.contains(object);
941         }
942 
943         @Override public boolean containsAll(Collection<?> collection) {
944             return c.containsAll(collection);
945         }
946 
947         @Override public boolean isEmpty() {
948             return c.isEmpty();
949         }
950 
951         @Override public Iterator<E> iterator() {
952             return new Iterator<E>() {
953                 Iterator<E> iterator = c.iterator();
954 
955                 @Override public boolean hasNext() {
956                     return iterator.hasNext();
957                 }
958 
959                 @Override public E next() {
960                     return iterator.next();
961                 }
962 
963                 @Override public void remove() {
964                     throw new UnsupportedOperationException();
965                 }
966             };
967         }
968 
969         @Override public boolean remove(Object object) {
970             throw new UnsupportedOperationException();
971         }
972 
973         @Override public boolean removeAll(Collection<?> collection) {
974             throw new UnsupportedOperationException();
975         }
976 
977         @Override public boolean retainAll(Collection<?> collection) {
978             throw new UnsupportedOperationException();
979         }
980 
981         @Override public int size() {
982             return c.size();
983         }
984 
985         @Override public Object[] toArray() {
986             return c.toArray();
987         }
988 
989         @Override public <T> T[] toArray(T[] array) {
990             return c.toArray(array);
991         }
992 
993         @Override public String toString() {
994             return c.toString();
995         }
996     }
997 
998     private static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
999             implements RandomAccess {
1000         private static final long serialVersionUID = -2542308836966382001L;
1001 
1002         UnmodifiableRandomAccessList(List<E> l) {
1003             super(l);
1004         }
1005 
1006         @Override public List<E> subList(int start, int end) {
1007             return new UnmodifiableRandomAccessList<E>(list.subList(start, end));
1008         }
1009 
1010         /**
1011          * Replaces this UnmodifiableRandomAccessList with an UnmodifiableList
1012          * so that JREs before 1.4 can deserialize this object without any
1013          * problems. This is necessary since RandomAccess API was introduced
1014          * only in 1.4.
1015          * <p>
1016          *
1017          * @return UnmodifiableList
1018          *
1019          * @see UnmodifiableList#readResolve()
1020          */
1021         private Object writeReplace() {
1022             return new UnmodifiableList<E>(list);
1023         }
1024     }
1025 
1026     private static class UnmodifiableList<E> extends UnmodifiableCollection<E>
1027             implements List<E> {
1028         private static final long serialVersionUID = -283967356065247728L;
1029 
1030         final List<E> list;
1031 
1032         UnmodifiableList(List<E> l) {
1033             super(l);
1034             list = l;
1035         }
1036 
1037         @Override public void add(int location, E object) {
1038             throw new UnsupportedOperationException();
1039         }
1040 
1041         @Override public boolean addAll(int location, Collection<? extends E> collection) {
1042             throw new UnsupportedOperationException();
1043         }
1044 
1045         @Override public boolean equals(Object object) {
1046             return list.equals(object);
1047         }
1048 
1049         @Override public E get(int location) {
1050             return list.get(location);
1051         }
1052 
1053         @Override public int hashCode() {
1054             return list.hashCode();
1055         }
1056 
1057         @Override public int indexOf(Object object) {
1058             return list.indexOf(object);
1059         }
1060 
1061         @Override public int lastIndexOf(Object object) {
1062             return list.lastIndexOf(object);
1063         }
1064 
1065         @Override public ListIterator<E> listIterator() {
1066             return listIterator(0);
1067         }
1068 
1069         @Override public ListIterator<E> listIterator(final int location) {
1070             return new ListIterator<E>() {
1071                 ListIterator<E> iterator = list.listIterator(location);
1072 
1073                 @Override public void add(E object) {
1074                     throw new UnsupportedOperationException();
1075                 }
1076 
1077                 @Override public boolean hasNext() {
1078                     return iterator.hasNext();
1079                 }
1080 
1081                 @Override public boolean hasPrevious() {
1082                     return iterator.hasPrevious();
1083                 }
1084 
1085                 @Override public E next() {
1086                     return iterator.next();
1087                 }
1088 
1089                 @Override public int nextIndex() {
1090                     return iterator.nextIndex();
1091                 }
1092 
1093                 @Override public E previous() {
1094                     return iterator.previous();
1095                 }
1096 
1097                 @Override public int previousIndex() {
1098                     return iterator.previousIndex();
1099                 }
1100 
1101                 @Override public void remove() {
1102                     throw new UnsupportedOperationException();
1103                 }
1104 
1105                 @Override public void set(E object) {
1106                     throw new UnsupportedOperationException();
1107                 }
1108             };
1109         }
1110 
1111         @Override public E remove(int location) {
1112             throw new UnsupportedOperationException();
1113         }
1114 
1115         @Override public E set(int location, E object) {
1116             throw new UnsupportedOperationException();
1117         }
1118 
1119         @Override public List<E> subList(int start, int end) {
1120             return new UnmodifiableList<E>(list.subList(start, end));
1121         }
1122 
1123         /**
1124          * Resolves UnmodifiableList instances to UnmodifiableRandomAccessList
1125          * instances if the underlying list is a Random Access list.
1126          * <p>
1127          * This is necessary since UnmodifiableRandomAccessList instances are
1128          * replaced with UnmodifiableList instances during serialization for
1129          * compliance with JREs before 1.4.
1130          * <p>
1131          *
1132          * @return an UnmodifiableList instance if the underlying list
1133          *         implements RandomAccess interface, or this same object if
1134          *         not.
1135          *
1136          * @see UnmodifiableRandomAccessList#writeReplace()
1137          */
1138         private Object readResolve() {
1139             if (list instanceof RandomAccess) {
1140                 return new UnmodifiableRandomAccessList<E>(list);
1141             }
1142             return this;
1143         }
1144     }
1145 
1146     private static class UnmodifiableMap<K, V> implements Map<K, V>,
1147             Serializable {
1148         private static final long serialVersionUID = -1034234728574286014L;
1149 
1150         private final Map<K, V> m;
1151 
1152         private static class UnmodifiableEntrySet<K, V> extends
1153                 UnmodifiableSet<Map.Entry<K, V>> {
1154             private static final long serialVersionUID = 7854390611657943733L;
1155 
1156             private static class UnmodifiableMapEntry<K, V> implements
1157                     Map.Entry<K, V> {
1158                 Map.Entry<K, V> mapEntry;
1159 
1160                 UnmodifiableMapEntry(Map.Entry<K, V> entry) {
1161                     mapEntry = entry;
1162                 }
1163 
1164                 @Override public boolean equals(Object object) {
1165                     return mapEntry.equals(object);
1166                 }
1167 
1168                 @Override public K getKey() {
1169                     return mapEntry.getKey();
1170                 }
1171 
1172                 @Override public V getValue() {
1173                     return mapEntry.getValue();
1174                 }
1175 
1176                 @Override public int hashCode() {
1177                     return mapEntry.hashCode();
1178                 }
1179 
1180                 @Override public V setValue(V object) {
1181                     throw new UnsupportedOperationException();
1182                 }
1183 
1184                 @Override public String toString() {
1185                     return mapEntry.toString();
1186                 }
1187             }
1188 
1189             UnmodifiableEntrySet(Set<Map.Entry<K, V>> set) {
1190                 super(set);
1191             }
1192 
1193             @Override public Iterator<Map.Entry<K, V>> iterator() {
1194                 return new Iterator<Map.Entry<K, V>>() {
1195                     Iterator<Map.Entry<K, V>> iterator = c.iterator();
1196 
1197                     @Override public boolean hasNext() {
1198                         return iterator.hasNext();
1199                     }
1200 
1201                     @Override public Map.Entry<K, V> next() {
1202                         return new UnmodifiableMapEntry<K, V>(iterator.next());
1203                     }
1204 
1205                     @Override public void remove() {
1206                         throw new UnsupportedOperationException();
1207                     }
1208                 };
1209             }
1210 
1211             @Override public Object[] toArray() {
1212                 int length = c.size();
1213                 Object[] result = new Object[length];
1214                 Iterator<?> it = iterator();
1215                 for (int i = 0; i < length; i++) {
1216                     result[i] = it.next();
1217                 }
1218                 return result;
1219             }
1220 
1221             @SuppressWarnings("unchecked")
1222             @Override public <T> T[] toArray(T[] contents) {
1223                 int size = c.size(), index = 0;
1224                 Iterator<Map.Entry<K, V>> it = iterator();
1225                 if (size > contents.length) {
1226                     Class<?> ct = contents.getClass().getComponentType();
1227                     contents = (T[]) Array.newInstance(ct, size);
1228                 }
1229                 while (index < size) {
1230                     contents[index++] = (T) it.next();
1231                 }
1232                 if (index < contents.length) {
1233                     contents[index] = null;
1234                 }
1235                 return contents;
1236             }
1237         }
1238 
1239         UnmodifiableMap(Map<K, V> map) {
1240             m = map;
1241         }
1242 
1243         @Override public void clear() {
1244             throw new UnsupportedOperationException();
1245         }
1246 
1247         @Override public boolean containsKey(Object key) {
1248             return m.containsKey(key);
1249         }
1250 
1251         @Override public boolean containsValue(Object value) {
1252             return m.containsValue(value);
1253         }
1254 
1255         @Override public Set<Map.Entry<K, V>> entrySet() {
1256             return new UnmodifiableEntrySet<K, V>(m.entrySet());
1257         }
1258 
1259         @Override public boolean equals(Object object) {
1260             return m.equals(object);
1261         }
1262 
1263         @Override public V get(Object key) {
1264             return m.get(key);
1265         }
1266 
1267         @Override public int hashCode() {
1268             return m.hashCode();
1269         }
1270 
1271         @Override public boolean isEmpty() {
1272             return m.isEmpty();
1273         }
1274 
1275         @Override public Set<K> keySet() {
1276             return new UnmodifiableSet<K>(m.keySet());
1277         }
1278 
1279         @Override public V put(K key, V value) {
1280             throw new UnsupportedOperationException();
1281         }
1282 
1283         @Override public void putAll(Map<? extends K, ? extends V> map) {
1284             throw new UnsupportedOperationException();
1285         }
1286 
1287         @Override public V remove(Object key) {
1288             throw new UnsupportedOperationException();
1289         }
1290 
1291         @Override public int size() {
1292             return m.size();
1293         }
1294 
1295         @Override public Collection<V> values() {
1296             return new UnmodifiableCollection<V>(m.values());
1297         }
1298 
1299         @Override public String toString() {
1300             return m.toString();
1301         }
1302     }
1303 
1304     private static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
1305             implements Set<E> {
1306         private static final long serialVersionUID = -9215047833775013803L;
1307 
1308         UnmodifiableSet(Set<E> set) {
1309             super(set);
1310         }
1311 
1312         @Override public boolean equals(Object object) {
1313             return c.equals(object);
1314         }
1315 
1316         @Override public int hashCode() {
1317             return c.hashCode();
1318         }
1319     }
1320 
1321     private static class UnmodifiableSortedMap<K, V> extends
1322             UnmodifiableMap<K, V> implements SortedMap<K, V> {
1323         private static final long serialVersionUID = -8806743815996713206L;
1324 
1325         private final SortedMap<K, V> sm;
1326 
1327         UnmodifiableSortedMap(SortedMap<K, V> map) {
1328             super(map);
1329             sm = map;
1330         }
1331 
1332         @Override public Comparator<? super K> comparator() {
1333             return sm.comparator();
1334         }
1335 
1336         @Override public K firstKey() {
1337             return sm.firstKey();
1338         }
1339 
1340         @Override public SortedMap<K, V> headMap(K before) {
1341             return new UnmodifiableSortedMap<K, V>(sm.headMap(before));
1342         }
1343 
1344         @Override public K lastKey() {
1345             return sm.lastKey();
1346         }
1347 
1348         @Override public SortedMap<K, V> subMap(K start, K end) {
1349             return new UnmodifiableSortedMap<K, V>(sm.subMap(start, end));
1350         }
1351 
1352         @Override public SortedMap<K, V> tailMap(K after) {
1353             return new UnmodifiableSortedMap<K, V>(sm.tailMap(after));
1354         }
1355     }
1356 
1357     private static class UnmodifiableSortedSet<E> extends UnmodifiableSet<E>
1358             implements SortedSet<E> {
1359         private static final long serialVersionUID = -4929149591599911165L;
1360 
1361         private final SortedSet<E> ss;
1362 
1363         UnmodifiableSortedSet(SortedSet<E> set) {
1364             super(set);
1365             ss = set;
1366         }
1367 
1368         @Override public Comparator<? super E> comparator() {
1369             return ss.comparator();
1370         }
1371 
1372         @Override public E first() {
1373             return ss.first();
1374         }
1375 
1376         @Override public SortedSet<E> headSet(E before) {
1377             return new UnmodifiableSortedSet<E>(ss.headSet(before));
1378         }
1379 
1380         @Override public E last() {
1381             return ss.last();
1382         }
1383 
1384         @Override public SortedSet<E> subSet(E start, E end) {
1385             return new UnmodifiableSortedSet<E>(ss.subSet(start, end));
1386         }
1387 
1388         @Override public SortedSet<E> tailSet(E after) {
1389             return new UnmodifiableSortedSet<E>(ss.tailSet(after));
1390         }
1391     }
1392 
1393     private Collections() {}
1394 
1395     /**
1396      * Performs a binary search for the specified element in the specified
1397      * sorted list. The list needs to be already sorted in natural sorting
1398      * order. Searching in an unsorted array has an undefined result. It's also
1399      * undefined which element is found if there are multiple occurrences of the
1400      * same element.
1401      *
1402      * @param list
1403      *            the sorted list to search.
1404      * @param object
1405      *            the element to find.
1406      * @return the non-negative index of the element, or a negative index which
1407      *         is the {@code -index - 1} where the element would be inserted
1408      * @throws ClassCastException
1409      *             if an element in the List or the search element does not
1410      *             implement Comparable, or cannot be compared to each other.
1411      */
1412     @SuppressWarnings("unchecked")
1413     public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T object) {
1414         if (list == null) {
1415             throw new NullPointerException("list == null");
1416         }
1417         if (list.isEmpty()) {
1418             return -1;
1419         }
1420 
1421 
1422         if (!(list instanceof RandomAccess)) {
1423             ListIterator<? extends Comparable<? super T>> it = list.listIterator();
1424             while (it.hasNext()) {
1425                 int result;
1426                 if ((result = -it.next().compareTo(object)) <= 0) {
1427                     if (result == 0) {
1428                         return it.previousIndex();
1429                     }
1430                     return -it.previousIndex() - 1;
1431                 }
1432             }
1433             return -list.size() - 1;
1434         }
1435 
1436         int low = 0, mid = list.size(), high = mid - 1, result = -1;
1437         while (low <= high) {
1438             mid = (low + high) >>> 1;
1439             if ((result = -list.get(mid).compareTo(object)) > 0) {
1440                 low = mid + 1;
1441             } else if (result == 0) {
1442                 return mid;
1443             } else {
1444                 high = mid - 1;
1445             }
1446         }
1447         return -mid - (result < 0 ? 1 : 2);
1448     }
1449 
1450     /**
1451      * Performs a binary search for the specified element in the specified
1452      * sorted list using the specified comparator. The list needs to be already
1453      * sorted according to the comparator passed. Searching in an unsorted array
1454      * has an undefined result. It's also undefined which element is found if
1455      * there are multiple occurrences of the same element.
1456      *
1457      * @param list
1458      *            the sorted List to search.
1459      * @param object
1460      *            the element to find.
1461      * @param comparator
1462      *            the comparator. If the comparator is {@code null} then the
1463      *            search uses the objects' natural ordering.
1464      * @return the non-negative index of the element, or a negative index which
1465      *         is the {@code -index - 1} where the element would be inserted.
1466      * @throws ClassCastException
1467      *             when an element in the list and the searched element cannot
1468      *             be compared to each other using the comparator.
1469      */
1470     @SuppressWarnings("unchecked")
1471     public static <T> int binarySearch(List<? extends T> list, T object,
1472             Comparator<? super T> comparator) {
1473         if (comparator == null) {
1474             return Collections.binarySearch(
1475                     (List<? extends Comparable<? super T>>) list, object);
1476         }
1477         if (!(list instanceof RandomAccess)) {
1478             ListIterator<? extends T> it = list.listIterator();
1479             while (it.hasNext()) {
1480                 int result;
1481                 if ((result = -comparator.compare(it.next(), object)) <= 0) {
1482                     if (result == 0) {
1483                         return it.previousIndex();
1484                     }
1485                     return -it.previousIndex() - 1;
1486                 }
1487             }
1488             return -list.size() - 1;
1489         }
1490 
1491         int low = 0, mid = list.size(), high = mid - 1, result = -1;
1492         while (low <= high) {
1493             mid = (low + high) >>> 1;
1494             if ((result = -comparator.compare(list.get(mid), object)) > 0) {
1495                 low = mid + 1;
1496             } else if (result == 0) {
1497                 return mid;
1498             } else {
1499                 high = mid - 1;
1500             }
1501         }
1502         return -mid - (result < 0 ? 1 : 2);
1503     }
1504 
1505     /**
1506      * Copies the elements from the source list to the destination list. At the
1507      * end both lists will have the same objects at the same index. If the
1508      * destination array is larger than the source list, the elements in the
1509      * destination list with {@code index >= source.size()} will be unchanged.
1510      *
1511      * @param destination
1512      *            the list whose elements are set from the source list.
1513      * @param source
1514      *            the list with the elements to be copied into the destination.
1515      * @throws IndexOutOfBoundsException
1516      *             when the destination list is smaller than the source list.
1517      * @throws UnsupportedOperationException
1518      *             when replacing an element in the destination list is not
1519      *             supported.
1520      */
1521     public static <T> void copy(List<? super T> destination, List<? extends T> source) {
1522         if (destination.size() < source.size()) {
1523             throw new IndexOutOfBoundsException("destination.size() < source.size(): " +
1524                     destination.size() + " < " + source.size());
1525         }
1526         Iterator<? extends T> srcIt = source.iterator();
1527         ListIterator<? super T> destIt = destination.listIterator();
1528         while (srcIt.hasNext()) {
1529             try {
1530                 destIt.next();
1531             } catch (NoSuchElementException e) {
1532                 // TODO: AssertionError?
1533                 throw new IndexOutOfBoundsException("Source size " + source.size() +
1534                         " does not fit into destination");
1535             }
1536             destIt.set(srcIt.next());
1537         }
1538     }
1539 
1540     /**
1541      * Returns an {@code Enumeration} on the specified collection.
1542      *
1543      * @param collection
1544      *            the collection to enumerate.
1545      * @return an Enumeration.
1546      */
1547     public static <T> Enumeration<T> enumeration(Collection<T> collection) {
1548         final Collection<T> c = collection;
1549         return new Enumeration<T>() {
1550             Iterator<T> it = c.iterator();
1551 
1552             @Override public boolean hasMoreElements() {
1553                 return it.hasNext();
1554             }
1555 
1556             @Override public T nextElement() {
1557                 return it.next();
1558             }
1559         };
1560     }
1561 
1562     /**
1563      * Fills the specified list with the specified element.
1564      *
1565      * @param list
1566      *            the list to fill.
1567      * @param object
1568      *            the element to fill the list with.
1569      * @throws UnsupportedOperationException
1570      *             when replacing an element in the List is not supported.
1571      */
1572     public static <T> void fill(List<? super T> list, T object) {
1573         ListIterator<? super T> it = list.listIterator();
1574         while (it.hasNext()) {
1575             it.next();
1576             it.set(object);
1577         }
1578     }
1579 
1580     /**
1581      * Searches the specified collection for the maximum element.
1582      *
1583      * @param collection
1584      *            the collection to search.
1585      * @return the maximum element in the Collection.
1586      * @throws ClassCastException
1587      *             when an element in the collection does not implement
1588      *             {@code Comparable} or elements cannot be compared to each
1589      *             other.
1590      */
1591     public static <T extends Object & Comparable<? super T>> T max(
1592             Collection<? extends T> collection) {
1593         Iterator<? extends T> it = collection.iterator();
1594         T max = it.next();
1595         while (it.hasNext()) {
1596             T next = it.next();
1597             if (max.compareTo(next) < 0) {
1598                 max = next;
1599             }
1600         }
1601         return max;
1602     }
1603 
1604     /**
1605      * Searches the specified collection for the maximum element using the
1606      * specified comparator.
1607      *
1608      * @param collection
1609      *            the collection to search.
1610      * @param comparator
1611      *            the comparator.
1612      * @return the maximum element in the Collection.
1613      * @throws ClassCastException
1614      *             when elements in the collection cannot be compared to each
1615      *             other using the {@code Comparator}.
1616      */
1617     public static <T> T max(Collection<? extends T> collection,
1618             Comparator<? super T> comparator) {
1619         if (comparator == null) {
1620             @SuppressWarnings("unchecked") // null comparator? T is comparable
1621             T result = (T) max((Collection<Comparable>) collection);
1622             return result;
1623         }
1624 
1625         Iterator<? extends T> it = collection.iterator();
1626         T max = it.next();
1627         while (it.hasNext()) {
1628             T next = it.next();
1629             if (comparator.compare(max, next) < 0) {
1630                 max = next;
1631             }
1632         }
1633         return max;
1634     }
1635 
1636     /**
1637      * Searches the specified collection for the minimum element.
1638      *
1639      * @param collection
1640      *            the collection to search.
1641      * @return the minimum element in the collection.
1642      * @throws ClassCastException
1643      *             when an element in the collection does not implement
1644      *             {@code Comparable} or elements cannot be compared to each
1645      *             other.
1646      */
1647     public static <T extends Object & Comparable<? super T>> T min(
1648             Collection<? extends T> collection) {
1649         Iterator<? extends T> it = collection.iterator();
1650         T min = it.next();
1651         while (it.hasNext()) {
1652             T next = it.next();
1653             if (min.compareTo(next) > 0) {
1654                 min = next;
1655             }
1656         }
1657         return min;
1658     }
1659 
1660     /**
1661      * Searches the specified collection for the minimum element using the
1662      * specified comparator.
1663      *
1664      * @param collection
1665      *            the collection to search.
1666      * @param comparator
1667      *            the comparator.
1668      * @return the minimum element in the collection.
1669      * @throws ClassCastException
1670      *             when elements in the collection cannot be compared to each
1671      *             other using the {@code Comparator}.
1672      */
1673     public static <T> T min(Collection<? extends T> collection,
1674             Comparator<? super T> comparator) {
1675         if (comparator == null) {
1676             @SuppressWarnings("unchecked") // null comparator? T is comparable
1677             T result = (T) min((Collection<Comparable>) collection);
1678             return result;
1679         }
1680 
1681         Iterator<? extends T> it = collection.iterator();
1682         T min = it.next();
1683         while (it.hasNext()) {
1684             T next = it.next();
1685             if (comparator.compare(min, next) > 0) {
1686                 min = next;
1687             }
1688         }
1689         return min;
1690     }
1691 
1692     /**
1693      * Returns a list containing the specified number of the specified element.
1694      * The list cannot be modified. The list is serializable.
1695      *
1696      * @param length
1697      *            the size of the returned list.
1698      * @param object
1699      *            the element to be added {@code length} times to a list.
1700      * @return a list containing {@code length} copies of the element.
1701      * @throws IllegalArgumentException
1702      *             when {@code length < 0}.
1703      */
1704     public static <T> List<T> nCopies(final int length, T object) {
1705         return new CopiesList<T>(length, object);
1706     }
1707 
1708     /**
1709      * Modifies the specified {@code List} by reversing the order of the
1710      * elements.
1711      *
1712      * @param list
1713      *            the list to reverse.
1714      * @throws UnsupportedOperationException
1715      *             when replacing an element in the List is not supported.
1716      */
1717     @SuppressWarnings("unchecked")
1718     public static void reverse(List<?> list) {
1719         int size = list.size();
1720         ListIterator<Object> front = (ListIterator<Object>) list.listIterator();
1721         ListIterator<Object> back = (ListIterator<Object>) list
1722                 .listIterator(size);
1723         for (int i = 0; i < size / 2; i++) {
1724             Object frontNext = front.next();
1725             Object backPrev = back.previous();
1726             front.set(backPrev);
1727             back.set(frontNext);
1728         }
1729     }
1730 
1731     /**
1732      * A comparator which reverses the natural order of the elements. The
1733      * {@code Comparator} that's returned is {@link Serializable}.
1734      *
1735      * @return a {@code Comparator} instance.
1736      */
1737     @SuppressWarnings("unchecked")
1738     public static <T> Comparator<T> reverseOrder() {
1739         return (Comparator) ReverseComparator.INSTANCE;
1740     }
1741 
1742     /**
1743      * Returns a {@link Comparator} that reverses the order of the
1744      * {@code Comparator} passed. If the {@code Comparator} passed is
1745      * {@code null}, then this method is equivalent to {@link #reverseOrder()}.
1746      * <p>
1747      * The {@code Comparator} that's returned is {@link Serializable} if the
1748      * {@code Comparator} passed is serializable or {@code null}.
1749      *
1750      * @param c
1751      *            the {@code Comparator} to reverse or {@code null}.
1752      * @return a {@code Comparator} instance.
1753      * @since 1.5
1754      */
1755     public static <T> Comparator<T> reverseOrder(Comparator<T> c) {
1756         if (c == null) {
1757             return reverseOrder();
1758         }
1759         if (c instanceof ReverseComparator2) {
1760             return ((ReverseComparator2<T>) c).cmp;
1761         }
1762         return new ReverseComparator2<T>(c);
1763     }
1764 
1765     /**
1766      * Moves every element of the list to a random new position in the list.
1767      *
1768      * @param list
1769      *            the List to shuffle.
1770      *
1771      * @throws UnsupportedOperationException
1772      *             when replacing an element in the List is not supported.
1773      */
1774     public static void shuffle(List<?> list) {
1775         shuffle(list, new Random());
1776     }
1777 
1778     /**
1779      * Moves every element of the list to a random new position in the list
1780      * using the specified random number generator.
1781      *
1782      * @param list
1783      *            the list to shuffle.
1784      * @param random
1785      *            the random number generator.
1786      * @throws UnsupportedOperationException
1787      *             when replacing an element in the list is not supported.
1788      */
1789     public static void shuffle(List<?> list, Random random) {
1790         @SuppressWarnings("unchecked") // we won't put foreign objects in
1791         final List<Object> objectList = (List<Object>) list;
1792 
1793         if (list instanceof RandomAccess) {
1794             for (int i = objectList.size() - 1; i > 0; i--) {
1795                 int index = random.nextInt(i + 1);
1796                 objectList.set(index, objectList.set(i, objectList.get(index)));
1797             }
1798         } else {
1799             Object[] array = objectList.toArray();
1800             for (int i = array.length - 1; i > 0; i--) {
1801                 int index = random.nextInt(i + 1);
1802                 Object temp = array[i];
1803                 array[i] = array[index];
1804                 array[index] = temp;
1805             }
1806 
1807             int i = 0;
1808             ListIterator<Object> it = objectList.listIterator();
1809             while (it.hasNext()) {
1810                 it.next();
1811                 it.set(array[i++]);
1812             }
1813         }
1814     }
1815 
1816     /**
1817      * Returns a set containing the specified element. The set cannot be
1818      * modified. The set is serializable.
1819      *
1820      * @param object
1821      *            the element.
1822      * @return a set containing the element.
1823      */
1824     public static <E> Set<E> singleton(E object) {
1825         return new SingletonSet<E>(object);
1826     }
1827 
1828     /**
1829      * Returns a list containing the specified element. The list cannot be
1830      * modified. The list is serializable.
1831      *
1832      * @param object
1833      *            the element.
1834      * @return a list containing the element.
1835      */
1836     public static <E> List<E> singletonList(E object) {
1837         return new SingletonList<E>(object);
1838     }
1839 
1840     /**
1841      * Returns a Map containing the specified key and value. The map cannot be
1842      * modified. The map is serializable.
1843      *
1844      * @param key
1845      *            the key.
1846      * @param value
1847      *            the value.
1848      * @return a Map containing the key and value.
1849      */
1850     public static <K, V> Map<K, V> singletonMap(K key, V value) {
1851         return new SingletonMap<K, V>(key, value);
1852     }
1853 
1854     /**
1855      * Sorts the given list in ascending natural order. The algorithm is
1856      * stable which means equal elements don't get reordered.
1857      *
1858      * @throws ClassCastException if any element does not implement {@code Comparable},
1859      *     or if {@code compareTo} throws for any pair of elements.
1860      */
1861     @SuppressWarnings("unchecked")
1862     public static <T extends Comparable<? super T>> void sort(List<T> list) {
1863         Object[] array = list.toArray();
1864         Arrays.sort(array);
1865         int i = 0;
1866         ListIterator<T> it = list.listIterator();
1867         while (it.hasNext()) {
1868             it.next();
1869             it.set((T) array[i++]);
1870         }
1871     }
1872 
1873     /**
1874      * Sorts the given list using the given comparator. The algorithm is
1875      * stable which means equal elements don't get reordered.
1876      *
1877      * @throws ClassCastException if any element does not implement {@code Comparable},
1878      *     or if {@code compareTo} throws for any pair of elements.
1879      */
1880     @SuppressWarnings("unchecked")
1881     public static <T> void sort(List<T> list, Comparator<? super T> comparator) {
1882         T[] array = list.toArray((T[]) new Object[list.size()]);
1883         Arrays.sort(array, comparator);
1884         int i = 0;
1885         ListIterator<T> it = list.listIterator();
1886         while (it.hasNext()) {
1887             it.next();
1888             it.set(array[i++]);
1889         }
1890     }
1891 
1892     /**
1893      * Swaps the elements of list {@code list} at indices {@code index1} and
1894      * {@code index2}.
1895      *
1896      * @param list
1897      *            the list to manipulate.
1898      * @param index1
1899      *            position of the first element to swap with the element in
1900      *            index2.
1901      * @param index2
1902      *            position of the other element.
1903      *
1904      * @throws IndexOutOfBoundsException
1905      *             if index1 or index2 is out of range of this list.
1906      * @since 1.4
1907      */
1908     @SuppressWarnings("unchecked")
1909     public static void swap(List<?> list, int index1, int index2) {
1910         if (list == null) {
1911             throw new NullPointerException("list == null");
1912         }
1913         final int size = list.size();
1914         if (index1 < 0 || index1 >= size || index2 < 0 || index2 >= size) {
1915             throw new IndexOutOfBoundsException();
1916         }
1917         if (index1 == index2) {
1918             return;
1919         }
1920         List<Object> rawList = (List<Object>) list;
1921         rawList.set(index2, rawList.set(index1, rawList.get(index2)));
1922     }
1923 
1924     /**
1925      * Replaces all occurrences of Object {@code obj} in {@code list} with
1926      * {@code newObj}. If the {@code obj} is {@code null}, then all
1927      * occurrences of {@code null} are replaced with {@code newObj}.
1928      *
1929      * @param list
1930      *            the list to modify.
1931      * @param obj
1932      *            the object to find and replace occurrences of.
1933      * @param obj2
1934      *            the object to replace all occurrences of {@code obj} in
1935      *            {@code list}.
1936      * @return true, if at least one occurrence of {@code obj} has been found in
1937      *         {@code list}.
1938      * @throws UnsupportedOperationException
1939      *             if the list does not support setting elements.
1940      */
1941     public static <T> boolean replaceAll(List<T> list, T obj, T obj2) {
1942         int index;
1943         boolean found = false;
1944 
1945         while ((index = list.indexOf(obj)) > -1) {
1946             found = true;
1947             list.set(index, obj2);
1948         }
1949         return found;
1950     }
1951 
1952     /**
1953      * Rotates the elements in {@code list} by the distance {@code dist}
1954      * <p>
1955      * e.g. for a given list with elements [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
1956      * calling rotate(list, 3) or rotate(list, -7) would modify the list to look
1957      * like this: [8, 9, 0, 1, 2, 3, 4, 5, 6, 7]
1958      *
1959      * @param lst
1960      *            the list whose elements are to be rotated.
1961      * @param dist
1962      *            is the distance the list is rotated. This can be any valid
1963      *            integer. Negative values rotate the list backwards.
1964      */
1965     @SuppressWarnings("unchecked")
1966     public static void rotate(List<?> lst, int dist) {
1967         List<Object> list = (List<Object>) lst;
1968         int size = list.size();
1969 
1970         // Can't sensibly rotate an empty collection
1971         if (size == 0) {
1972             return;
1973         }
1974 
1975         // normalize the distance
1976         int normdist;
1977         if (dist > 0) {
1978             normdist = dist % size;
1979         } else {
1980             normdist = size - ((dist % size) * (-1));
1981         }
1982 
1983         if (normdist == 0 || normdist == size) {
1984             return;
1985         }
1986 
1987         if (list instanceof RandomAccess) {
1988             // make sure each element gets juggled
1989             // with the element in the position it is supposed to go to
1990             Object temp = list.get(0);
1991             int index = 0, beginIndex = 0;
1992             for (int i = 0; i < size; i++) {
1993                 index = (index + normdist) % size;
1994                 temp = list.set(index, temp);
1995                 if (index == beginIndex) {
1996                     index = ++beginIndex;
1997                     temp = list.get(beginIndex);
1998                 }
1999             }
2000         } else {
2001             int divideIndex = (size - normdist) % size;
2002             List<Object> sublist1 = list.subList(0, divideIndex);
2003             List<Object> sublist2 = list.subList(divideIndex, size);
2004             reverse(sublist1);
2005             reverse(sublist2);
2006             reverse(list);
2007         }
2008     }
2009 
2010     /**
2011      * Searches the {@code list} for {@code sublist} and returns the beginning
2012      * index of the first occurrence.
2013      * <p>
2014      * -1 is returned if the {@code sublist} does not exist in {@code list}.
2015      *
2016      * @param list
2017      *            the List to search {@code sublist} in.
2018      * @param sublist
2019      *            the List to search in {@code list}.
2020      * @return the beginning index of the first occurrence of {@code sublist} in
2021      *         {@code list}, or -1.
2022      */
2023     public static int indexOfSubList(List<?> list, List<?> sublist) {
2024         int size = list.size();
2025         int sublistSize = sublist.size();
2026 
2027         if (sublistSize > size) {
2028             return -1;
2029         }
2030 
2031         if (sublistSize == 0) {
2032             return 0;
2033         }
2034 
2035         // find the first element of sublist in the list to get a head start
2036         Object firstObj = sublist.get(0);
2037         int index = list.indexOf(firstObj);
2038         if (index == -1) {
2039             return -1;
2040         }
2041 
2042         while (index < size && (size - index >= sublistSize)) {
2043             ListIterator<?> listIt = list.listIterator(index);
2044 
2045             if ((firstObj == null) ? listIt.next() == null : firstObj
2046                     .equals(listIt.next())) {
2047 
2048                 // iterate through the elements in sublist to see
2049                 // if they are included in the same order in the list
2050                 ListIterator<?> sublistIt = sublist.listIterator(1);
2051                 boolean difFound = false;
2052                 while (sublistIt.hasNext()) {
2053                     Object element = sublistIt.next();
2054                     if (!listIt.hasNext()) {
2055                         return -1;
2056                     }
2057                     if ((element == null) ? listIt.next() != null : !element
2058                             .equals(listIt.next())) {
2059                         difFound = true;
2060                         break;
2061                     }
2062                 }
2063                 // All elements of sublist are found in main list
2064                 // starting from index.
2065                 if (!difFound) {
2066                     return index;
2067                 }
2068             }
2069             // This was not the sequence we were looking for,
2070             // continue search for the firstObj in main list
2071             // at the position after index.
2072             index++;
2073         }
2074         return -1;
2075     }
2076 
2077     /**
2078      * Searches the {@code list} for {@code sublist} and returns the beginning
2079      * index of the last occurrence.
2080      * <p>
2081      * -1 is returned if the {@code sublist} does not exist in {@code list}.
2082      *
2083      * @param list
2084      *            the list to search {@code sublist} in.
2085      * @param sublist
2086      *            the list to search in {@code list}.
2087      * @return the beginning index of the last occurrence of {@code sublist} in
2088      *         {@code list}, or -1.
2089      */
2090     public static int lastIndexOfSubList(List<?> list, List<?> sublist) {
2091         int sublistSize = sublist.size();
2092         int size = list.size();
2093 
2094         if (sublistSize > size) {
2095             return -1;
2096         }
2097 
2098         if (sublistSize == 0) {
2099             return size;
2100         }
2101 
2102         // find the last element of sublist in the list to get a head start
2103         Object lastObj = sublist.get(sublistSize - 1);
2104         int index = list.lastIndexOf(lastObj);
2105 
2106         while ((index > -1) && (index + 1 >= sublistSize)) {
2107             ListIterator<?> listIt = list.listIterator(index + 1);
2108 
2109             if ((lastObj == null) ? listIt.previous() == null : lastObj
2110                     .equals(listIt.previous())) {
2111                 // iterate through the elements in sublist to see
2112                 // if they are included in the same order in the list
2113                 ListIterator<?> sublistIt = sublist
2114                         .listIterator(sublistSize - 1);
2115                 boolean difFound = false;
2116                 while (sublistIt.hasPrevious()) {
2117                     Object element = sublistIt.previous();
2118                     if (!listIt.hasPrevious()) {
2119                         return -1;
2120                     }
2121                     if ((element == null) ? listIt.previous() != null
2122                             : !element.equals(listIt.previous())) {
2123                         difFound = true;
2124                         break;
2125                     }
2126                 }
2127                 // All elements of sublist are found in main list
2128                 // starting from listIt.nextIndex().
2129                 if (!difFound) {
2130                     return listIt.nextIndex();
2131                 }
2132             }
2133             // This was not the sequence we were looking for,
2134             // continue search for the lastObj in main list
2135             // at the position before index.
2136             index--;
2137         }
2138         return -1;
2139     }
2140 
2141     /**
2142      * Returns an {@code ArrayList} with all the elements in the {@code
2143      * enumeration}. The elements in the returned {@code ArrayList} are in the
2144      * same order as in the {@code enumeration}.
2145      *
2146      * @param enumeration
2147      *            the source {@link Enumeration}.
2148      * @return an {@code ArrayList} from {@code enumeration}.
2149      */
2150     public static <T> ArrayList<T> list(Enumeration<T> enumeration) {
2151         ArrayList<T> list = new ArrayList<T>();
2152         while (enumeration.hasMoreElements()) {
2153             list.add(enumeration.nextElement());
2154         }
2155         return list;
2156     }
2157 
2158     /**
2159      * Returns a wrapper on the specified collection which synchronizes all
2160      * access to the collection.
2161      *
2162      * @param collection
2163      *            the Collection to wrap in a synchronized collection.
2164      * @return a synchronized Collection.
2165      */
2166     public static <T> Collection<T> synchronizedCollection(
2167             Collection<T> collection) {
2168         if (collection == null) {
2169             throw new NullPointerException("collection == null");
2170         }
2171         return new SynchronizedCollection<T>(collection);
2172     }
2173 
2174     /**
2175      * Returns a wrapper on the specified List which synchronizes all access to
2176      * the List.
2177      *
2178      * @param list
2179      *            the List to wrap in a synchronized list.
2180      * @return a synchronized List.
2181      */
2182     public static <T> List<T> synchronizedList(List<T> list) {
2183         if (list == null) {
2184             throw new NullPointerException("list == null");
2185         }
2186         if (list instanceof RandomAccess) {
2187             return new SynchronizedRandomAccessList<T>(list);
2188         }
2189         return new SynchronizedList<T>(list);
2190     }
2191 
2192     /**
2193      * Returns a wrapper on the specified map which synchronizes all access to
2194      * the map.
2195      *
2196      * @param map
2197      *            the map to wrap in a synchronized map.
2198      * @return a synchronized Map.
2199      */
2200     public static <K, V> Map<K, V> synchronizedMap(Map<K, V> map) {
2201         if (map == null) {
2202             throw new NullPointerException("map == null");
2203         }
2204         return new SynchronizedMap<K, V>(map);
2205     }
2206 
2207     /**
2208      * Returns a wrapper on the specified set which synchronizes all access to
2209      * the set.
2210      *
2211      * @param set
2212      *            the set to wrap in a synchronized set.
2213      * @return a synchronized set.
2214      */
2215     public static <E> Set<E> synchronizedSet(Set<E> set) {
2216         if (set == null) {
2217             throw new NullPointerException("set == null");
2218         }
2219         return new SynchronizedSet<E>(set);
2220     }
2221 
2222     /**
2223      * Returns a wrapper on the specified sorted map which synchronizes all
2224      * access to the sorted map.
2225      *
2226      * @param map
2227      *            the sorted map to wrap in a synchronized sorted map.
2228      * @return a synchronized sorted map.
2229      */
2230     public static <K, V> SortedMap<K, V> synchronizedSortedMap(
2231             SortedMap<K, V> map) {
2232         if (map == null) {
2233             throw new NullPointerException("map == null");
2234         }
2235         return new SynchronizedSortedMap<K, V>(map);
2236     }
2237 
2238     /**
2239      * Returns a wrapper on the specified sorted set which synchronizes all
2240      * access to the sorted set.
2241      *
2242      * @param set
2243      *            the sorted set to wrap in a synchronized sorted set.
2244      * @return a synchronized sorted set.
2245      */
2246     public static <E> SortedSet<E> synchronizedSortedSet(SortedSet<E> set) {
2247         if (set == null) {
2248             throw new NullPointerException("set == null");
2249         }
2250         return new SynchronizedSortedSet<E>(set);
2251     }
2252 
2253     /**
2254      * Returns a wrapper on the specified collection which throws an
2255      * {@code UnsupportedOperationException} whenever an attempt is made to
2256      * modify the collection.
2257      *
2258      * @param collection
2259      *            the collection to wrap in an unmodifiable collection.
2260      * @return an unmodifiable collection.
2261      */
2262     @SuppressWarnings("unchecked")
2263     public static <E> Collection<E> unmodifiableCollection(
2264             Collection<? extends E> collection) {
2265         if (collection == null) {
2266             throw new NullPointerException("collection == null");
2267         }
2268         return new UnmodifiableCollection<E>((Collection<E>) collection);
2269     }
2270 
2271     /**
2272      * Returns a wrapper on the specified list which throws an
2273      * {@code UnsupportedOperationException} whenever an attempt is made to
2274      * modify the list.
2275      *
2276      * @param list
2277      *            the list to wrap in an unmodifiable list.
2278      * @return an unmodifiable List.
2279      */
2280     @SuppressWarnings("unchecked")
2281     public static <E> List<E> unmodifiableList(List<? extends E> list) {
2282         if (list == null) {
2283             throw new NullPointerException("list == null");
2284         }
2285         if (list instanceof RandomAccess) {
2286             return new UnmodifiableRandomAccessList<E>((List<E>) list);
2287         }
2288         return new UnmodifiableList<E>((List<E>) list);
2289     }
2290 
2291     /**
2292      * Returns a wrapper on the specified map which throws an
2293      * {@code UnsupportedOperationException} whenever an attempt is made to
2294      * modify the map.
2295      *
2296      * @param map
2297      *            the map to wrap in an unmodifiable map.
2298      * @return a unmodifiable map.
2299      */
2300     @SuppressWarnings("unchecked")
2301     public static <K, V> Map<K, V> unmodifiableMap(
2302             Map<? extends K, ? extends V> map) {
2303         if (map == null) {
2304             throw new NullPointerException("map == null");
2305         }
2306         return new UnmodifiableMap<K, V>((Map<K, V>) map);
2307     }
2308 
2309     /**
2310      * Returns a wrapper on the specified set which throws an
2311      * {@code UnsupportedOperationException} whenever an attempt is made to
2312      * modify the set.
2313      *
2314      * @param set
2315      *            the set to wrap in an unmodifiable set.
2316      * @return a unmodifiable set
2317      */
2318     @SuppressWarnings("unchecked")
2319     public static <E> Set<E> unmodifiableSet(Set<? extends E> set) {
2320         if (set == null) {
2321             throw new NullPointerException("set == null");
2322         }
2323         return new UnmodifiableSet<E>((Set<E>) set);
2324     }
2325 
2326     /**
2327      * Returns a wrapper on the specified sorted map which throws an
2328      * {@code UnsupportedOperationException} whenever an attempt is made to
2329      * modify the sorted map.
2330      *
2331      * @param map
2332      *            the sorted map to wrap in an unmodifiable sorted map.
2333      * @return a unmodifiable sorted map
2334      */
2335     @SuppressWarnings("unchecked")
2336     public static <K, V> SortedMap<K, V> unmodifiableSortedMap(
2337             SortedMap<K, ? extends V> map) {
2338         if (map == null) {
2339             throw new NullPointerException("map == null");
2340         }
2341         return new UnmodifiableSortedMap<K, V>((SortedMap<K, V>) map);
2342     }
2343 
2344     /**
2345      * Returns a wrapper on the specified sorted set which throws an
2346      * {@code UnsupportedOperationException} whenever an attempt is made to
2347      * modify the sorted set.
2348      *
2349      * @param set
2350      *            the sorted set to wrap in an unmodifiable sorted set.
2351      * @return a unmodifiable sorted set.
2352      */
2353     public static <E> SortedSet<E> unmodifiableSortedSet(SortedSet<E> set) {
2354         if (set == null) {
2355             throw new NullPointerException("set == null");
2356         }
2357         return new UnmodifiableSortedSet<E>(set);
2358     }
2359 
2360     /**
2361      * Returns the number of elements in the {@code Collection} that match the
2362      * {@code Object} passed. If the {@code Object} is {@code null}, then the
2363      * number of {@code null} elements is returned.
2364      *
2365      * @param c
2366      *            the {@code Collection} to search.
2367      * @param o
2368      *            the {@code Object} to search for.
2369      * @return the number of matching elements.
2370      * @throws NullPointerException
2371      *             if the {@code Collection} parameter is {@code null}.
2372      * @since 1.5
2373      */
2374     public static int frequency(Collection<?> c, Object o) {
2375         if (c == null) {
2376             throw new NullPointerException("c == null");
2377         }
2378         if (c.isEmpty()) {
2379             return 0;
2380         }
2381         int result = 0;
2382         Iterator<?> itr = c.iterator();
2383         while (itr.hasNext()) {
2384             Object e = itr.next();
2385             if (o == null ? e == null : o.equals(e)) {
2386                 result++;
2387             }
2388         }
2389         return result;
2390     }
2391 
2392     /**
2393      * Returns a type-safe empty, immutable {@link List}.
2394      *
2395      * @return an empty {@link List}.
2396      * @since 1.5
2397      * @see #EMPTY_LIST
2398      */
2399     @SuppressWarnings("unchecked")
2400     public static final <T> List<T> emptyList() {
2401         return EMPTY_LIST;
2402     }
2403 
2404     /**
2405      * Returns a type-safe empty, immutable {@link Set}.
2406      *
2407      * @return an empty {@link Set}.
2408      * @since 1.5
2409      * @see #EMPTY_SET
2410      */
2411     @SuppressWarnings("unchecked")
2412     public static final <T> Set<T> emptySet() {
2413         return EMPTY_SET;
2414     }
2415 
2416     /**
2417      * Returns a type-safe empty, immutable {@link Map}.
2418      *
2419      * @return an empty {@link Map}.
2420      * @since 1.5
2421      * @see #EMPTY_MAP
2422      */
2423     @SuppressWarnings("unchecked")
2424     public static final <K, V> Map<K, V> emptyMap() {
2425         return EMPTY_MAP;
2426     }
2427 
2428     /**
2429      * Returns an enumeration containing no elements.
2430      * @since 1.7
2431      */
2432     @SuppressWarnings("unchecked")
2433     public static <T> Enumeration<T> emptyEnumeration() {
2434         return (Enumeration<T>) EMPTY_ENUMERATION;
2435     }
2436 
2437     /**
2438      * Returns an iterator containing no elements.
2439      * @since 1.7
2440      */
2441     @SuppressWarnings("unchecked")
2442     public static <T> Iterator<T> emptyIterator() {
2443         return (Iterator<T>) EMPTY_ITERATOR;
2444     }
2445 
2446     /**
2447      * Returns a list iterator containing no elements.
2448      * @since 1.7
2449      */
2450     public static <T> ListIterator<T> emptyListIterator() {
2451         return Collections.<T>emptyList().listIterator();
2452     }
2453 
2454     /**
2455      * Returns a dynamically typesafe view of the specified collection. Trying
2456      * to insert an element of the wrong type into this collection throws a
2457      * {@code ClassCastException}. At creation time the types in {@code c} are
2458      * not checked for correct type.
2459      *
2460      * @param c
2461      *            the collection to be wrapped in a typesafe collection.
2462      * @param type
2463      *            the type of the elements permitted to insert.
2464      * @return a typesafe collection.
2465      */
2466     public static <E> Collection<E> checkedCollection(Collection<E> c,
2467             Class<E> type) {
2468         return new CheckedCollection<E>(c, type);
2469     }
2470 
2471     /**
2472      * Returns a dynamically typesafe view of the specified map. Trying to
2473      * insert an element of the wrong type into this map throws a
2474      * {@code ClassCastException}. At creation time the types in {@code m} are
2475      * not checked for correct type.
2476      *
2477      * @param m
2478      *            the map to be wrapped in a typesafe map.
2479      * @param keyType
2480      *            the type of the keys permitted to insert.
2481      * @param valueType
2482      *            the type of the values permitted to insert.
2483      * @return a typesafe map.
2484      */
2485     public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType,
2486             Class<V> valueType) {
2487         return new CheckedMap<K, V>(m, keyType, valueType);
2488     }
2489 
2490     /**
2491      * Returns a dynamically typesafe view of the specified list. Trying to
2492      * insert an element of the wrong type into this list throws a
2493      * {@code ClassCastException}. At creation time the types in {@code list}
2494      * are not checked for correct type.
2495      *
2496      * @param list
2497      *            the list to be wrapped in a typesafe list.
2498      * @param type
2499      *            the type of the elements permitted to insert.
2500      * @return a typesafe list.
2501      */
2502     public static <E> List<E> checkedList(List<E> list, Class<E> type) {
2503         if (list instanceof RandomAccess) {
2504             return new CheckedRandomAccessList<E>(list, type);
2505         }
2506         return new CheckedList<E>(list, type);
2507     }
2508 
2509     /**
2510      * Returns a dynamically typesafe view of the specified set. Trying to
2511      * insert an element of the wrong type into this set throws a
2512      * {@code ClassCastException}. At creation time the types in {@code s} are
2513      * not checked for correct type.
2514      *
2515      * @param s
2516      *            the set to be wrapped in a typesafe set.
2517      * @param type
2518      *            the type of the elements permitted to insert.
2519      * @return a typesafe set.
2520      */
2521     public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
2522         return new CheckedSet<E>(s, type);
2523     }
2524 
2525     /**
2526      * Returns a dynamically typesafe view of the specified sorted map. Trying
2527      * to insert an element of the wrong type into this sorted map throws a
2528      * {@code ClassCastException}. At creation time the types in {@code m} are
2529      * not checked for correct type.
2530      *
2531      * @param m
2532      *            the sorted map to be wrapped in a typesafe sorted map.
2533      * @param keyType
2534      *            the type of the keys permitted to insert.
2535      * @param valueType
2536      *            the type of the values permitted to insert.
2537      * @return a typesafe sorted map.
2538      */
2539     public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m,
2540             Class<K> keyType, Class<V> valueType) {
2541         return new CheckedSortedMap<K, V>(m, keyType, valueType);
2542     }
2543 
2544     /**
2545      * Returns a dynamically typesafe view of the specified sorted set. Trying
2546      * to insert an element of the wrong type into this sorted set throws a
2547      * {@code ClassCastException}. At creation time the types in {@code s} are
2548      * not checked for correct type.
2549      *
2550      * @param s
2551      *            the sorted set to be wrapped in a typesafe sorted set.
2552      * @param type
2553      *            the type of the elements permitted to insert.
2554      * @return a typesafe sorted set.
2555      */
2556     public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
2557             Class<E> type) {
2558         return new CheckedSortedSet<E>(s, type);
2559     }
2560 
2561     /**
2562      * Adds all the specified elements to the specified collection.
2563      *
2564      * @param c
2565      *            the collection the elements are to be inserted into.
2566      * @param a
2567      *            the elements to insert.
2568      * @return true if the collection changed during insertion.
2569      * @throws UnsupportedOperationException
2570      *             when the method is not supported.
2571      * @throws NullPointerException
2572      *             when {@code c} or {@code a} is {@code null}, or {@code a}
2573      *             contains one or more {@code null} elements and {@code c}
2574      *             doesn't support {@code null} elements.
2575      * @throws IllegalArgumentException
2576      *             if at least one of the elements can't be inserted into the
2577      *             collection.
2578      */
2579     @SafeVarargs
2580     public static <T> boolean addAll(Collection<? super T> c, T... a) {
2581         boolean modified = false;
2582         for (int i = 0; i < a.length; i++) {
2583             modified |= c.add(a[i]);
2584         }
2585         return modified;
2586     }
2587 
2588     /**
2589      * Returns whether the specified collections have no elements in common.
2590      *
2591      * @param c1
2592      *            the first collection.
2593      * @param c2
2594      *            the second collection.
2595      * @return {@code true} if the collections have no elements in common,
2596      *         {@code false} otherwise.
2597      * @throws NullPointerException
2598      *             if one of the collections is {@code null}.
2599      */
2600     public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
2601         if ((c1 instanceof Set) && !(c2 instanceof Set)
2602                 || (c2.size()) > c1.size()) {
2603             Collection<?> tmp = c1;
2604             c1 = c2;
2605             c2 = tmp;
2606         }
2607         Iterator<?> it = c1.iterator();
2608         while (it.hasNext()) {
2609             if (c2.contains(it.next())) {
2610                 return false;
2611             }
2612         }
2613         return true;
2614     }
2615 
2616     /**
2617      * Checks if specified object is instance of specified class. Used for a
2618      * dynamically typesafe view of the collections.
2619      *
2620      * @param obj -
2621      *            object is to be checked
2622      * @param type -
2623      *            class of object that should be
2624      * @return specified object
2625      */
2626     static <E> E checkType(E obj, Class<? extends E> type) {
2627         if (obj != null && !type.isInstance(obj)) {
2628             throw new ClassCastException("Attempt to insert element of type " + obj.getClass() +
2629                     " into collection of type " + type);
2630         }
2631         return obj;
2632     }
2633 
2634     /**
2635      * Returns a set backed by {@code map}.
2636      *
2637      * @throws IllegalArgumentException if the map is not empty
2638      * @since 1.6
2639      */
2640     public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
2641         if (map.isEmpty()) {
2642             return new SetFromMap<E>(map);
2643         }
2644         throw new IllegalArgumentException("map not empty");
2645     }
2646 
2647     /**
2648      * Returns a last-in, first-out queue as a view of {@code deque}.
2649      *
2650      * @since 1.6
2651      */
2652     public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
2653         return new AsLIFOQueue<T>(deque);
2654     }
2655 
2656     private static class SetFromMap<E> extends AbstractSet<E> implements Serializable {
2657         private static final long serialVersionUID = 2454657854757543876L;
2658 
2659         // Must be named as is, to pass serialization compatibility test.
2660         private final Map<E, Boolean> m;
2661 
2662         private transient Set<E> backingSet;
2663 
2664         SetFromMap(final Map<E, Boolean> map) {
2665             m = map;
2666             backingSet = map.keySet();
2667         }
2668 
2669         @Override public boolean equals(Object object) {
2670             return backingSet.equals(object);
2671         }
2672 
2673         @Override public int hashCode() {
2674             return backingSet.hashCode();
2675         }
2676 
2677         @Override public boolean add(E object) {
2678             return m.put(object, Boolean.TRUE) == null;
2679         }
2680 
2681         @Override public void clear() {
2682             m.clear();
2683         }
2684 
2685         @Override public String toString() {
2686             return backingSet.toString();
2687         }
2688 
2689         @Override public boolean contains(Object object) {
2690             return backingSet.contains(object);
2691         }
2692 
2693         @Override public boolean containsAll(Collection<?> collection) {
2694             return backingSet.containsAll(collection);
2695         }
2696 
2697         @Override public boolean isEmpty() {
2698             return m.isEmpty();
2699         }
2700 
2701         @Override public boolean remove(Object object) {
2702             return m.remove(object) != null;
2703         }
2704 
2705         @Override public boolean retainAll(Collection<?> collection) {
2706             return backingSet.retainAll(collection);
2707         }
2708 
2709         @Override public Object[] toArray() {
2710             return backingSet.toArray();
2711         }
2712 
2713         @Override
2714         public <T> T[] toArray(T[] contents) {
2715             return backingSet.toArray(contents);
2716         }
2717 
2718         @Override public Iterator<E> iterator() {
2719             return backingSet.iterator();
2720         }
2721 
2722         @Override public int size() {
2723             return m.size();
2724         }
2725 
2726         @SuppressWarnings("unchecked")
2727         private void readObject(ObjectInputStream stream)
2728                 throws IOException, ClassNotFoundException {
2729             stream.defaultReadObject();
2730             backingSet = m.keySet();
2731         }
2732     }
2733 
2734     private static class AsLIFOQueue<E> extends AbstractQueue<E> implements Serializable {
2735         private static final long serialVersionUID = 1802017725587941708L;
2736 
2737         // Must be named as is, to pass serialization compatibility test.
2738         private final Deque<E> q;
2739 
2740         AsLIFOQueue(final Deque<E> deque) {
2741             this.q = deque;
2742         }
2743 
2744         @Override public Iterator<E> iterator() {
2745             return q.iterator();
2746         }
2747 
2748         @Override public int size() {
2749             return q.size();
2750         }
2751 
2752         @Override public boolean offer(E o) {
2753             return q.offerFirst(o);
2754         }
2755 
2756         @Override public E peek() {
2757             return q.peekFirst();
2758         }
2759 
2760         @Override public E poll() {
2761             return q.pollFirst();
2762         }
2763 
2764         @Override public boolean add(E o) {
2765             q.push(o);
2766             return true;
2767         }
2768 
2769         @Override public void clear() {
2770             q.clear();
2771         }
2772 
2773         @Override public E element() {
2774             return q.getFirst();
2775         }
2776 
2777         @Override public E remove() {
2778             return q.pop();
2779         }
2780 
2781         @Override public boolean contains(Object object) {
2782             return q.contains(object);
2783         }
2784 
2785         @Override public boolean containsAll(Collection<?> collection) {
2786             return q.containsAll(collection);
2787         }
2788 
2789         @Override public boolean isEmpty() {
2790             return q.isEmpty();
2791         }
2792 
2793         @Override public boolean remove(Object object) {
2794             return q.remove(object);
2795         }
2796 
2797         @Override public boolean removeAll(Collection<?> collection) {
2798             return q.removeAll(collection);
2799         }
2800 
2801         @Override public boolean retainAll(Collection<?> collection) {
2802             return q.retainAll(collection);
2803         }
2804 
2805         @Override public Object[] toArray() {
2806             return q.toArray();
2807         }
2808 
2809         @Override public <T> T[] toArray(T[] contents) {
2810             return q.toArray(contents);
2811         }
2812 
2813         @Override public String toString() {
2814             return q.toString();
2815         }
2816     }
2817 
2818     /**
2819      * A dynamically typesafe view of a Collection.
2820      */
2821     private static class CheckedCollection<E> implements Collection<E>, Serializable {
2822 
2823         private static final long serialVersionUID = 1578914078182001775L;
2824 
2825         final Collection<E> c;
2826 
2827         final Class<E> type;
2828 
2829         public CheckedCollection(Collection<E> c, Class<E> type) {
2830             if (c == null) {
2831                 throw new NullPointerException("c == null");
2832             } else if (type == null) {
2833                 throw new NullPointerException("type == null");
2834             }
2835             this.c = c;
2836             this.type = type;
2837         }
2838 
2839         @Override public int size() {
2840             return c.size();
2841         }
2842 
2843         @Override public boolean isEmpty() {
2844             return c.isEmpty();
2845         }
2846 
2847         @Override public boolean contains(Object obj) {
2848             return c.contains(obj);
2849         }
2850 
2851         @Override public Iterator<E> iterator() {
2852             Iterator<E> i = c.iterator();
2853             if (i instanceof ListIterator) {
2854                 i = new CheckedListIterator<E>((ListIterator<E>) i, type);
2855             }
2856             return i;
2857         }
2858 
2859         @Override public Object[] toArray() {
2860             return c.toArray();
2861         }
2862 
2863         @Override public <T> T[] toArray(T[] arr) {
2864             return c.toArray(arr);
2865         }
2866 
2867         @Override public boolean add(E obj) {
2868             return c.add(checkType(obj, type));
2869         }
2870 
2871         @Override public boolean remove(Object obj) {
2872             return c.remove(obj);
2873         }
2874 
2875         @Override public boolean containsAll(Collection<?> c1) {
2876             return c.containsAll(c1);
2877         }
2878 
2879         @SuppressWarnings("unchecked")
2880         @Override public boolean addAll(Collection<? extends E> c1) {
2881             Object[] array = c1.toArray();
2882             for (Object o : array) {
2883                 checkType(o, type);
2884             }
2885             return c.addAll((List<E>) Arrays.asList(array));
2886         }
2887 
2888         @Override public boolean removeAll(Collection<?> c1) {
2889             return c.removeAll(c1);
2890         }
2891 
2892         @Override public boolean retainAll(Collection<?> c1) {
2893             return c.retainAll(c1);
2894         }
2895 
2896         @Override public void clear() {
2897             c.clear();
2898         }
2899 
2900         @Override public String toString() {
2901             return c.toString();
2902         }
2903     }
2904 
2905     /**
2906      * Class represents a dynamically typesafe view of the specified
2907      * ListIterator.
2908      */
2909     private static class CheckedListIterator<E> implements ListIterator<E> {
2910 
2911         private final ListIterator<E> i;
2912 
2913         private final Class<E> type;
2914 
2915         /**
2916          * Constructs a dynamically typesafe view of the specified ListIterator.
2917          *
2918          * @param i -
2919          *            the listIterator for which a dynamically typesafe view to
2920          *            be constructed.
2921          */
2922         public CheckedListIterator(ListIterator<E> i, Class<E> type) {
2923             this.i = i;
2924             this.type = type;
2925         }
2926 
2927         @Override public boolean hasNext() {
2928             return i.hasNext();
2929         }
2930 
2931         @Override public E next() {
2932             return i.next();
2933         }
2934 
2935         @Override public void remove() {
2936             i.remove();
2937         }
2938 
2939         @Override public boolean hasPrevious() {
2940             return i.hasPrevious();
2941         }
2942 
2943         @Override public E previous() {
2944             return i.previous();
2945         }
2946 
2947         @Override public int nextIndex() {
2948             return i.nextIndex();
2949         }
2950 
2951         @Override public int previousIndex() {
2952             return i.previousIndex();
2953         }
2954 
2955         @Override public void set(E obj) {
2956             i.set(checkType(obj, type));
2957         }
2958 
2959         @Override public void add(E obj) {
2960             i.add(checkType(obj, type));
2961         }
2962     }
2963 
2964     /**
2965      * Class represents a dynamically typesafe view of a List.
2966      */
2967     private static class CheckedList<E> extends CheckedCollection<E> implements List<E> {
2968 
2969         private static final long serialVersionUID = 65247728283967356L;
2970 
2971         final List<E> l;
2972 
2973         public CheckedList(List<E> l, Class<E> type) {
2974             super(l, type);
2975             this.l = l;
2976         }
2977 
2978         @SuppressWarnings("unchecked")
2979         @Override public boolean addAll(int index, Collection<? extends E> c1) {
2980             Object[] array = c1.toArray();
2981             for (Object o : array) {
2982                 checkType(o, type);
2983             }
2984             return l.addAll(index, (List<E>) Arrays.asList(array));
2985         }
2986 
2987         @Override public E get(int index) {
2988             return l.get(index);
2989         }
2990 
2991         @Override public E set(int index, E obj) {
2992             return l.set(index, checkType(obj, type));
2993         }
2994 
2995         @Override public void add(int index, E obj) {
2996             l.add(index, checkType(obj, type));
2997         }
2998 
2999         @Override public E remove(int index) {
3000             return l.remove(index);
3001         }
3002 
3003         @Override public int indexOf(Object obj) {
3004             return l.indexOf(obj);
3005         }
3006 
3007         @Override public int lastIndexOf(Object obj) {
3008             return l.lastIndexOf(obj);
3009         }
3010 
3011         @Override public ListIterator<E> listIterator() {
3012             return new CheckedListIterator<E>(l.listIterator(), type);
3013         }
3014 
3015         @Override public ListIterator<E> listIterator(int index) {
3016             return new CheckedListIterator<E>(l.listIterator(index), type);
3017         }
3018 
3019         @Override public List<E> subList(int fromIndex, int toIndex) {
3020             return checkedList(l.subList(fromIndex, toIndex), type);
3021         }
3022 
3023         @Override public boolean equals(Object obj) {
3024             return l.equals(obj);
3025         }
3026 
3027         @Override public int hashCode() {
3028             return l.hashCode();
3029         }
3030     }
3031 
3032     /**
3033      * A dynamically typesafe view of a RandomAccessList.
3034      */
3035     private static class CheckedRandomAccessList<E> extends CheckedList<E> implements RandomAccess {
3036 
3037         private static final long serialVersionUID = 1638200125423088369L;
3038 
3039         public CheckedRandomAccessList(List<E> l, Class<E> type) {
3040             super(l, type);
3041         }
3042     }
3043 
3044     /**
3045      * A dynamically typesafe view of a Set.
3046      */
3047     private static class CheckedSet<E> extends CheckedCollection<E> implements Set<E> {
3048 
3049         private static final long serialVersionUID = 4694047833775013803L;
3050 
3051         public CheckedSet(Set<E> s, Class<E> type) {
3052             super(s, type);
3053         }
3054 
3055         @Override public boolean equals(Object obj) {
3056             return c.equals(obj);
3057         }
3058 
3059         @Override public int hashCode() {
3060             return c.hashCode();
3061         }
3062 
3063     }
3064 
3065     /**
3066      * A dynamically typesafe view of a Map.
3067      */
3068     private static class CheckedMap<K, V> implements Map<K, V>, Serializable {
3069 
3070         private static final long serialVersionUID = 5742860141034234728L;
3071 
3072         final Map<K, V> m;
3073         final Class<K> keyType;
3074         final Class<V> valueType;
3075 
3076         private CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
3077             if (m == null) {
3078                 throw new NullPointerException("m == null");
3079             } else if (keyType == null) {
3080                 throw new NullPointerException("keyType == null");
3081             } else if (valueType == null) {
3082                 throw new NullPointerException("valueType == null");
3083             }
3084             this.m = m;
3085             this.keyType = keyType;
3086             this.valueType = valueType;
3087         }
3088 
3089         @Override public int size() {
3090             return m.size();
3091         }
3092 
3093         @Override public boolean isEmpty() {
3094             return m.isEmpty();
3095         }
3096 
3097         @Override public boolean containsKey(Object key) {
3098             return m.containsKey(key);
3099         }
3100 
3101         @Override public boolean containsValue(Object value) {
3102             return m.containsValue(value);
3103         }
3104 
3105         @Override public V get(Object key) {
3106             return m.get(key);
3107         }
3108 
3109         @Override public V put(K key, V value) {
3110             return m.put(checkType(key, keyType), checkType(value, valueType));
3111         }
3112 
3113         @Override public V remove(Object key) {
3114             return m.remove(key);
3115         }
3116 
3117         @SuppressWarnings("unchecked")
3118         @Override public void putAll(Map<? extends K, ? extends V> map) {
3119             int size = map.size();
3120             if (size == 0) {
3121                 return;
3122             }
3123             Map.Entry<? extends K, ? extends V>[] entries = new Map.Entry[size];
3124             Iterator<? extends Map.Entry<? extends K, ? extends V>> it = map
3125                     .entrySet().iterator();
3126             for (int i = 0; i < size; i++) {
3127                 Map.Entry<? extends K, ? extends V> e = it.next();
3128                 checkType(e.getKey(), keyType);
3129                 checkType(e.getValue(), valueType);
3130                 entries[i] = e;
3131             }
3132             for (int i = 0; i < size; i++) {
3133                 m.put(entries[i].getKey(), entries[i].getValue());
3134             }
3135         }
3136 
3137         @Override public void clear() {
3138             m.clear();
3139         }
3140 
3141         @Override public Set<K> keySet() {
3142             return m.keySet();
3143         }
3144 
3145         @Override public Collection<V> values() {
3146             return m.values();
3147         }
3148 
3149         @Override public Set<Map.Entry<K, V>> entrySet() {
3150             return new CheckedEntrySet<K, V>(m.entrySet(), valueType);
3151         }
3152 
3153         @Override public boolean equals(Object obj) {
3154             return m.equals(obj);
3155         }
3156 
3157         @Override public int hashCode() {
3158             return m.hashCode();
3159         }
3160 
3161         @Override public String toString() {
3162             return m.toString();
3163         }
3164 
3165         /**
3166          * A dynamically typesafe view of a Map.Entry.
3167          */
3168         private static class CheckedEntry<K, V> implements Map.Entry<K, V> {
3169             final Map.Entry<K, V> e;
3170             final Class<V> valueType;
3171 
3172             public CheckedEntry(Map.Entry<K, V> e, Class<V> valueType) {
3173                 if (e == null) {
3174                     throw new NullPointerException("e == null");
3175                 }
3176                 this.e = e;
3177                 this.valueType = valueType;
3178             }
3179 
3180             @Override public K getKey() {
3181                 return e.getKey();
3182             }
3183 
3184             @Override public V getValue() {
3185                 return e.getValue();
3186             }
3187 
3188             @Override public V setValue(V obj) {
3189                 return e.setValue(checkType(obj, valueType));
3190             }
3191 
3192             @Override public boolean equals(Object obj) {
3193                 return e.equals(obj);
3194             }
3195 
3196             @Override public int hashCode() {
3197                 return e.hashCode();
3198             }
3199         }
3200 
3201         /**
3202          * A dynamically typesafe view of an entry set.
3203          */
3204         private static class CheckedEntrySet<K, V> implements Set<Map.Entry<K, V>> {
3205             final Set<Map.Entry<K, V>> s;
3206             final Class<V> valueType;
3207 
3208             public CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {
3209                 this.s = s;
3210                 this.valueType = valueType;
3211             }
3212 
3213             @Override public Iterator<Map.Entry<K, V>> iterator() {
3214                 return new CheckedEntryIterator<K, V>(s.iterator(), valueType);
3215             }
3216 
3217             @Override public Object[] toArray() {
3218                 int thisSize = size();
3219                 Object[] array = new Object[thisSize];
3220                 Iterator<?> it = iterator();
3221                 for (int i = 0; i < thisSize; i++) {
3222                     array[i] = it.next();
3223                 }
3224                 return array;
3225             }
3226 
3227             @SuppressWarnings("unchecked")
3228             @Override public <T> T[] toArray(T[] array) {
3229                 int thisSize = size();
3230                 if (array.length < thisSize) {
3231                     Class<?> ct = array.getClass().getComponentType();
3232                     array = (T[]) Array.newInstance(ct, thisSize);
3233                 }
3234                 Iterator<?> it = iterator();
3235                 for (int i = 0; i < thisSize; i++) {
3236                     array[i] = (T) it.next();
3237                 }
3238                 if (thisSize < array.length) {
3239                     array[thisSize] = null;
3240                 }
3241                 return array;
3242             }
3243 
3244             @Override public boolean retainAll(Collection<?> c) {
3245                 return s.retainAll(c);
3246             }
3247 
3248             @Override public boolean removeAll(Collection<?> c) {
3249                 return s.removeAll(c);
3250             }
3251 
3252             @Override public boolean containsAll(Collection<?> c) {
3253                 return s.containsAll(c);
3254             }
3255 
3256             @Override public boolean addAll(Collection<? extends Map.Entry<K, V>> c) {
3257                 throw new UnsupportedOperationException();
3258             }
3259 
3260             @Override public boolean remove(Object o) {
3261                 return s.remove(o);
3262             }
3263 
3264             @Override public boolean contains(Object o) {
3265                 return s.contains(o);
3266             }
3267 
3268             @Override public boolean add(Map.Entry<K, V> o) {
3269                 throw new UnsupportedOperationException();
3270             }
3271 
3272             @Override public boolean isEmpty() {
3273                 return s.isEmpty();
3274             }
3275 
3276             @Override public void clear() {
3277                 s.clear();
3278             }
3279 
3280             @Override public int size() {
3281                 return s.size();
3282             }
3283 
3284             @Override public int hashCode() {
3285                 return s.hashCode();
3286             }
3287 
3288             @Override public boolean equals(Object object) {
3289                 return s.equals(object);
3290             }
3291 
3292             /**
3293              * A dynamically typesafe view of an entry iterator.
3294              */
3295             private static class CheckedEntryIterator<K, V> implements Iterator<Map.Entry<K, V>> {
3296                 Iterator<Map.Entry<K, V>> i;
3297                 Class<V> valueType;
3298 
3299                 public CheckedEntryIterator(Iterator<Map.Entry<K, V>> i,
3300                         Class<V> valueType) {
3301                     this.i = i;
3302                     this.valueType = valueType;
3303                 }
3304 
3305                 @Override public boolean hasNext() {
3306                     return i.hasNext();
3307                 }
3308 
3309                 @Override public void remove() {
3310                     i.remove();
3311                 }
3312 
3313                 @Override public Map.Entry<K, V> next() {
3314                     return new CheckedEntry<K, V>(i.next(), valueType);
3315                 }
3316             }
3317         }
3318     }
3319 
3320     /**
3321      * A dynamically typesafe view of a SortedSet.
3322      */
3323     private static class CheckedSortedSet<E> extends CheckedSet<E> implements SortedSet<E> {
3324         private static final long serialVersionUID = 1599911165492914959L;
3325         private final SortedSet<E> ss;
3326 
3327         public CheckedSortedSet(SortedSet<E> s, Class<E> type) {
3328             super(s, type);
3329             this.ss = s;
3330         }
3331 
3332         @Override public Comparator<? super E> comparator() {
3333             return ss.comparator();
3334         }
3335 
3336         @Override public SortedSet<E> subSet(E fromElement, E toElement) {
3337             return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement),
3338                     type);
3339         }
3340 
3341         @Override public SortedSet<E> headSet(E toElement) {
3342             return new CheckedSortedSet<E>(ss.headSet(toElement), type);
3343         }
3344 
3345         @Override public SortedSet<E> tailSet(E fromElement) {
3346             return new CheckedSortedSet<E>(ss.tailSet(fromElement), type);
3347         }
3348 
3349         @Override public E first() {
3350             return ss.first();
3351         }
3352 
3353         @Override public E last() {
3354             return ss.last();
3355         }
3356     }
3357 
3358     /**
3359      * A dynamically typesafe view of a SortedMap.
3360      */
3361     private static class CheckedSortedMap<K, V> extends CheckedMap<K, V>
3362             implements SortedMap<K, V> {
3363         private static final long serialVersionUID = 1599671320688067438L;
3364         final SortedMap<K, V> sm;
3365 
3366         CheckedSortedMap(SortedMap<K, V> m, Class<K> keyType, Class<V> valueType) {
3367             super(m, keyType, valueType);
3368             this.sm = m;
3369         }
3370 
3371         @Override public Comparator<? super K> comparator() {
3372             return sm.comparator();
3373         }
3374 
3375         @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
3376             return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType, valueType);
3377         }
3378 
3379         @Override public SortedMap<K, V> headMap(K toKey) {
3380             return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType);
3381         }
3382 
3383         @Override public SortedMap<K, V> tailMap(K fromKey) {
3384             return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType, valueType);
3385         }
3386 
3387         @Override public K firstKey() {
3388             return sm.firstKey();
3389         }
3390 
3391         @Override public K lastKey() {
3392             return sm.lastKey();
3393         }
3394     }
3395 
3396     /**
3397      * Computes a hash code and applies a supplemental hash function to defend
3398      * against poor quality hash functions. This is critical because HashMap
3399      * uses power-of-two length hash tables, that otherwise encounter collisions
3400      * for hash codes that do not differ in lower or upper bits.
3401      * Routine taken from java.util.concurrent.ConcurrentHashMap.hash(int).
3402      * @hide
3403      */
3404     public static int secondaryHash(Object key) {
3405         return secondaryHash(key.hashCode());
3406     }
3407 
3408     /**
3409      * Computes an identity hash code and applies a supplemental hash function to defend
3410      * against poor quality hash functions. This is critical because identity hash codes
3411      * are currently implemented as object addresses, which will have been aligned by the
3412      * underlying memory allocator causing all hash codes to have the same bottom bits.
3413      * @hide
3414      */
3415     public static int secondaryIdentityHash(Object key) {
3416         return secondaryHash(System.identityHashCode(key));
3417     }
3418 
3419     private static int secondaryHash(int h) {
3420         // Spread bits to regularize both segment and index locations,
3421         // using variant of single-word Wang/Jenkins hash.
3422         h += (h <<  15) ^ 0xffffcd7d;
3423         h ^= (h >>> 10);
3424         h += (h <<   3);
3425         h ^= (h >>>  6);
3426         h += (h <<   2) + (h << 14);
3427         return h ^ (h >>> 16);
3428     }
3429 
3430     /**
3431      * Returns the smallest power of two >= its argument, with several caveats:
3432      * If the argument is negative but not Integer.MIN_VALUE, the method returns
3433      * zero. If the argument is > 2^30 or equal to Integer.MIN_VALUE, the method
3434      * returns Integer.MIN_VALUE. If the argument is zero, the method returns
3435      * zero.
3436      * @hide
3437      */
3438     public static int roundUpToPowerOfTwo(int i) {
3439         i--; // If input is a power of two, shift its high-order bit right.
3440 
3441         // "Smear" the high-order bit all the way to the right.
3442         i |= i >>>  1;
3443         i |= i >>>  2;
3444         i |= i >>>  4;
3445         i |= i >>>  8;
3446         i |= i >>> 16;
3447 
3448         return i + 1;
3449     }
3450 }
3451