12290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn/*
22290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Copyright (C) 2013 The Android Open Source Project
32290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
42290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
52290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * you may not use this file except in compliance with the License.
62290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * You may obtain a copy of the License at
72290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
82290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
92290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn *
102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Unless required by applicable law or agreed to in writing, software
112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * See the License for the specific language governing permissions and
142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * limitations under the License.
152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn */
162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
172290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornpackage android.support.v4.util;
182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
192290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.lang.reflect.Array;
202290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Collection;
212290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Iterator;
222290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Map;
232290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornimport java.util.Set;
242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn/**
262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * Helper for writing standard Java collection interfaces to a data
272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * structure like {@link ArrayMap}.
282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn * @hide
292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn */
302290993eddf5262a8df7fc9478daed52401e325aDianne Hackbornabstract class MapCollections<K, V> {
312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    EntrySet mEntrySet;
322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    KeySet mKeySet;
332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    ValuesCollection mValues;
342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class ArrayIterator<T> implements Iterator<T> {
362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int mOffset;
372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mSize;
382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mIndex;
392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        boolean mCanRemove = false;
402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        ArrayIterator(int offset) {
422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mOffset = offset;
432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mSize = colGetSize();
442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean hasNext() {
482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return mIndex < mSize;
492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public T next() {
532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Object res = colGetEntry(mIndex, mOffset);
542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex++;
552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mCanRemove = true;
562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (T)res;
572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void remove() {
612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mCanRemove) {
622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException();
632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex--;
652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mSize--;
662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mCanRemove = false;
672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colRemoveAt(mIndex);
682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> {
722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mEnd;
732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int mIndex;
742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        boolean mEntryValid = false;
752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        MapIterator() {
772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEnd = colGetSize() - 1;
782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex = -1;
792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean hasNext() {
832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return mIndex < mEnd;
842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Map.Entry<K, V> next() {
882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex++;
892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntryValid = true;
902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return this;
912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void remove() {
952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException();
972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
98138e0db47a8fe52d96d38c7be3fe9d2ad7f4083bAdam Lesinski            colRemoveAt(mIndex);
992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mIndex--;
1002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEnd--;
1012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntryValid = false;
1022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public K getKey() {
1062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (K)colGetEntry(mIndex, 0);
1112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public V getValue() {
1152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (V)colGetEntry(mIndex, 1);
1202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public V setValue(V object) {
1242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colSetValue(mIndex, object);
1292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public final boolean equals(Object o) {
1332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!(o instanceof Map.Entry)) {
1382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return false;
1392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return ContainerHelpers.equal(e.getKey(), colGetEntry(mIndex, 0))
1422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    && ContainerHelpers.equal(e.getValue(), colGetEntry(mIndex, 1));
1432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public final int hashCode() {
1472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!mEntryValid) {
1482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                throw new IllegalStateException(
1492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                        "This container does not support retaining Map.Entry objects");
1502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            final Object key = colGetEntry(mIndex, 0);
1522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            final Object value = colGetEntry(mIndex, 1);
1532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return (key == null ? 0 : key.hashCode()) ^
1542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    (value == null ? 0 : value.hashCode());
1552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public final String toString() {
1592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return getKey() + "=" + getValue();
1602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
1622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class EntrySet implements Set<Map.Entry<K, V>> {
1642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(Map.Entry<K, V> object) {
1662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
1672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) {
1712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int oldSize = colGetSize();
1722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (Map.Entry<K, V> entry : collection) {
1732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colPut(entry.getKey(), entry.getValue());
1742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
1752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return oldSize != colGetSize();
1762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
1802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
1812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
184d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean contains(Object o) {
185d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            if (!(o instanceof Map.Entry))
186d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
187d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
188d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int index = colIndexOfKey(e.getKey());
189d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            if (index < 0) {
190d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
191d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
192d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Object foundVal = colGetEntry(index, 1);
193d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return ContainerHelpers.equal(foundVal, e.getValue());
1942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
1952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
1962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
1972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
198d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Iterator<?> it = collection.iterator();
199d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            while (it.hasNext()) {
200d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                if (!contains(it.next())) {
201d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                    return false;
202d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                }
203d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
204d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return true;
2052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
2092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
2102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<Map.Entry<K, V>> iterator() {
2142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new MapIterator();
2152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
2192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
2242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
2292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
2342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
2352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
2392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
2442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
246d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
247d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
248d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean equals(Object object) {
249d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return equalsSetHelper(this, object);
250d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
251d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
252d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
253d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public int hashCode() {
254d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int result = 0;
255d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
256d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                final Object key = colGetEntry(i, 0);
257d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                final Object value = colGetEntry(i, 1);
258d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                result += ( (key == null ? 0 : key.hashCode()) ^
259d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                        (value == null ? 0 : value.hashCode()) );
260d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
261d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return result;
262d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
2632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
2642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class KeySet implements Set<K> {
2662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(K object) {
2692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends K> collection) {
2742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
2752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
2792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
2802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean contains(Object object) {
2842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colIndexOfKey(object) >= 0;
2852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
289d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return containsAllHelper(colGetMap(), collection);
2902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
2942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
2952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
2962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
2972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
2982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<K> iterator() {
2992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new ArrayIterator<K>(0);
3002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
3042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int index = colIndexOfKey(object);
3052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (index >= 0) {
3062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colRemoveAt(index);
3072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return true;
3082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
3092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return false;
3102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
3142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return removeAllHelper(colGetMap(), collection);
3152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
3192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return retainAllHelper(colGetMap(), collection);
3202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
3242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
3252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
3297b4c91bb218ce476748fc3fcecc71694a240d8cbDianne Hackborn            return toArrayHelper(0);
3302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
3347b4c91bb218ce476748fc3fcecc71694a240d8cbDianne Hackborn            return toArrayHelper(array, 0);
3352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
336d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
337d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
338d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public boolean equals(Object object) {
339d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return equalsSetHelper(this, object);
340d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
341d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
342d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        @Override
343d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        public int hashCode() {
344d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            int result = 0;
345d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
346d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                Object obj = colGetEntry(i, 0);
347d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                result += obj == null ? 0 : obj.hashCode();
348d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
349d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return result;
350d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
3512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
3522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    final class ValuesCollection implements Collection<V> {
3542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean add(V object) {
3572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
3582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean addAll(Collection<? extends V> collection) {
3622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            throw new UnsupportedOperationException();
3632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public void clear() {
3672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            colClear();
3682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean contains(Object object) {
3722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colIndexOfValue(object) >= 0;
3732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean containsAll(Collection<?> collection) {
3772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            Iterator<?> it = collection.iterator();
3782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            while (it.hasNext()) {
3792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (!contains(it.next())) {
3802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    return false;
3812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
3822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
3832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return true;
3842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean isEmpty() {
3882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize() == 0;
3892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Iterator<V> iterator() {
3932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return new ArrayIterator<V>(1);
3942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
3952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
3962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
3972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean remove(Object object) {
3982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int index = colIndexOfValue(object);
3992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (index >= 0) {
4002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                colRemoveAt(index);
4012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return true;
4022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return false;
4042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean removeAll(Collection<?> collection) {
4082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int N = colGetSize();
4092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            boolean changed = false;
4102290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (int i=0; i<N; i++) {
4112290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                Object cur = colGetEntry(i, 1);
4122290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (collection.contains(cur)) {
4132290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    colRemoveAt(i);
4142290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    i--;
4152290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    N--;
4162290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    changed = true;
4172290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
4182290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4192290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return changed;
4202290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4212290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4222290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4232290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public boolean retainAll(Collection<?> collection) {
4242290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            int N = colGetSize();
4252290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            boolean changed = false;
4262290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            for (int i=0; i<N; i++) {
4272290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                Object cur = colGetEntry(i, 1);
4282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                if (!collection.contains(cur)) {
4292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    colRemoveAt(i);
4302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    i--;
4312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    N--;
4322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                    changed = true;
4332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                }
4342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return changed;
4362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public int size() {
4402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return colGetSize();
4412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public Object[] toArray() {
4452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return toArrayHelper(1);
4462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        @Override
4492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        public <T> T[] toArray(T[] array) {
4502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            return toArrayHelper(array, 1);
4512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    };
4532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) {
4552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<?> it = collection.iterator();
4562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!map.containsKey(it.next())) {
4582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                return false;
4592290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4602290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4612290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return true;
4622290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4632290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4642290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) {
4652290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int oldSize = map.size();
4662290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<?> it = collection.iterator();
4672290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4682290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            map.remove(it.next());
4692290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4702290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return oldSize != map.size();
4712290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4722290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4732290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) {
4742290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        int oldSize = map.size();
4752290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Iterator<K> it = map.keySet().iterator();
4762290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        while (it.hasNext()) {
4772290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            if (!collection.contains(it.next())) {
4782290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                it.remove();
4792290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            }
4802290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4812290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return oldSize != map.size();
4822290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4832290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4842290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4852290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Object[] toArrayHelper(int offset) {
4862290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int N = colGetSize();
4872290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        Object[] result = new Object[N];
4882290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        for (int i=0; i<N; i++) {
4892290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            result[i] = colGetEntry(i, offset);
4902290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
4912290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return result;
4922290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
4932290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
4942290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public <T> T[] toArrayHelper(T[] array, int offset) {
4952290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        final int N  = colGetSize();
4962290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (array.length < N) {
4972290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            @SuppressWarnings("unchecked") T[] newArray
4982290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn                = (T[]) Array.newInstance(array.getClass().getComponentType(), N);
4992290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array = newArray;
5002290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5012290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        for (int i=0; i<N; i++) {
5022290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array[i] = (T)colGetEntry(i, offset);
5032290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5042290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (array.length > N) {
5052290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            array[N] = null;
5062290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5072290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return array;
5082290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5092290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
510d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn    public static <T> boolean equalsSetHelper(Set<T> set, Object object) {
511d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        if (set == object) {
512d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            return true;
513d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
514d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        if (object instanceof Set) {
515d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            Set<?> s = (Set<?>) object;
516d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
517d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            try {
518d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return set.size() == s.size() && set.containsAll(s);
519d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            } catch (NullPointerException ignored) {
520d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
521d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            } catch (ClassCastException ignored) {
522d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn                return false;
523d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn            }
524d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        }
525d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn        return false;
526d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn    }
527d682b566488c4ac3a8faae7d2eee5b6103d6f039Dianne Hackborn
5282290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Set<Map.Entry<K, V>> getEntrySet() {
5292290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mEntrySet == null) {
5302290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mEntrySet = new EntrySet();
5312290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5322290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mEntrySet;
5332290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5342290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5352290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Set<K> getKeySet() {
5362290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mKeySet == null) {
5372290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mKeySet = new KeySet();
5382290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5392290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mKeySet;
5402290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5412290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5422290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    public Collection<V> getValues() {
5432290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        if (mValues == null) {
5442290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn            mValues = new ValuesCollection();
5452290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        }
5462290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn        return mValues;
5472290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    }
5482290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn
5492290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colGetSize();
5502290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract Object colGetEntry(int index, int offset);
5512290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colIndexOfKey(Object key);
5522290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract int colIndexOfValue(Object key);
5532290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract Map<K, V> colGetMap();
5542290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colPut(K key, V value);
5552290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract V colSetValue(int index, V value);
5562290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colRemoveAt(int index);
5572290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn    protected abstract void colClear();
5582290993eddf5262a8df7fc9478daed52401e325aDianne Hackborn}
559