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
18package java.util;
19
20import java.io.IOException;
21import java.io.ObjectInputStream;
22import java.io.ObjectOutputStream;
23import java.io.ObjectStreamException;
24import java.io.Serializable;
25import 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 */
33public 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
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
72        @Override public boolean contains(Object object) {
73            return element == null ? object == null : element.equals(object);
74        }
75
76        @Override public int size() {
77            return n;
78        }
79
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
93        @Override public boolean contains(Object object) {
94            return false;
95        }
96
97        @Override public int size() {
98            return 0;
99        }
100
101        @Override public Object get(int location) {
102            throw new IndexOutOfBoundsException();
103        }
104
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
114        @Override public boolean contains(Object object) {
115            return false;
116        }
117
118        @Override public int size() {
119            return 0;
120        }
121
122        @Override public Iterator iterator() {
123            return EMPTY_ITERATOR;
124        }
125
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
135        @Override public boolean containsKey(Object key) {
136            return false;
137        }
138
139        @Override public boolean containsValue(Object value) {
140            return false;
141        }
142
143        @Override public Set entrySet() {
144            return EMPTY_SET;
145        }
146
147        @Override public Object get(Object key) {
148            return null;
149        }
150
151        @Override public Set keySet() {
152            return EMPTY_SET;
153        }
154
155        @Override public Collection values() {
156            return EMPTY_LIST;
157        }
158
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")
191        @Override public int compare(T o1, T o2) {
192            Comparable<T> c2 = (Comparable<T>) o2;
193            return c2.compareTo(o1);
194        }
195
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
205        ReverseComparator2(Comparator<T> comparator) {
206            this.cmp = comparator;
207        }
208
209        @Override public int compare(T o1, T o2) {
210            return cmp.compare(o2, o1);
211        }
212
213        @Override public boolean equals(Object o) {
214            return o instanceof ReverseComparator2
215                    && ((ReverseComparator2) o).cmp.equals(cmp);
216        }
217
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
227        SingletonSet(E object) {
228            element = object;
229        }
230
231        @Override public boolean contains(Object object) {
232            return element == null ? object == null : element.equals(object);
233        }
234
235        @Override public int size() {
236            return 1;
237        }
238
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
267        SingletonList(E object) {
268            element = object;
269        }
270
271        @Override public boolean contains(Object object) {
272            return element == null ? object == null : element.equals(object);
273        }
274
275        @Override public E get(int location) {
276            if (location == 0) {
277                return element;
278            }
279            throw new IndexOutOfBoundsException();
280        }
281
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
294        SingletonMap(K key, V value) {
295            k = key;
296            v = value;
297        }
298
299        @Override public boolean containsKey(Object key) {
300            return k == null ? key == null : k.equals(key);
301        }
302
303        @Override public boolean containsValue(Object value) {
304            return v == null ? value == null : v.equals(value);
305        }
306
307        @Override public V get(Object key) {
308            if (containsKey(key)) {
309                return v;
310            }
311            return null;
312        }
313
314        @Override public int size() {
315            return 1;
316        }
317
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 = length; --i >= 0;) {
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