1f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn/*
2f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * Copyright (C) 2013 The Android Open Source Project
3f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn *
4f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * you may not use this file except in compliance with the License.
6f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * You may obtain a copy of the License at
7f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn *
8f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn *
10f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * See the License for the specific language governing permissions and
14f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * limitations under the License.
15f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn */
16f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
17f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornpackage android.util;
18f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
19f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport libcore.util.Objects;
20f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
21f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport java.lang.reflect.Array;
22f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport java.util.Collection;
23f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport java.util.Iterator;
24f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport java.util.Map;
25f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornimport java.util.Set;
26f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
27f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn/**
28f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * Helper for writing standard Java collection interfaces to a data
29f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * structure like {@link ArrayMap}.
30f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn * @hide
31f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn */
32f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackbornabstract class MapCollections<K, V> {
33f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    EntrySet mEntrySet;
34f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    KeySet mKeySet;
35f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    ValuesCollection mValues;
36f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
37f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    final class ArrayIterator<T> implements Iterator<T> {
38f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        final int mOffset;
39f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int mSize;
40f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int mIndex;
41f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        boolean mCanRemove = false;
42f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
43f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        ArrayIterator(int offset) {
44f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mOffset = offset;
45f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mSize = colGetSize();
46f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
47f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
48f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
49f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean hasNext() {
50f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return mIndex < mSize;
51f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
52f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
53f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
54f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public T next() {
55f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            Object res = colGetEntry(mIndex, mOffset);
56f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mIndex++;
57f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mCanRemove = true;
58f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return (T)res;
59f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
60f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
61f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
62f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public void remove() {
63f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mCanRemove) {
64f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException();
65f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
66f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mIndex--;
67f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mSize--;
68f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mCanRemove = false;
69f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            colRemoveAt(mIndex);
70f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
71f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
72f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
73f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> {
74f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int mEnd;
75f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int mIndex;
76f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        boolean mEntryValid = false;
77f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
78f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        MapIterator() {
79f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mEnd = colGetSize() - 1;
80f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mIndex = -1;
81f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
82f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
83f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
84f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean hasNext() {
85f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return mIndex < mEnd;
86f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
87f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
88f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
89f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Map.Entry<K, V> next() {
90f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mIndex++;
91f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mEntryValid = true;
92f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return this;
93f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
94f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
95f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
96f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public void remove() {
97f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
98f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException();
99f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
10083c7ac3b8e5faadb73313c73d401803d5d52f55fAdam Lesinski            colRemoveAt(mIndex);
101f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mIndex--;
102f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mEnd--;
103f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mEntryValid = false;
104f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
105f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
106f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
107f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public K getKey() {
108f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
109f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException(
110f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                        "This container does not support retaining Map.Entry objects");
111f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
112f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return (K)colGetEntry(mIndex, 0);
113f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
114f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
115f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
116f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public V getValue() {
117f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
118f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException(
119f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                        "This container does not support retaining Map.Entry objects");
120f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
121f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return (V)colGetEntry(mIndex, 1);
122f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
123f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
124f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
125f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public V setValue(V object) {
126f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
127f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException(
128f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                        "This container does not support retaining Map.Entry objects");
129f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
130f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colSetValue(mIndex, object);
131f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
132f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
133f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
134f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public final boolean equals(Object o) {
135f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
136f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException(
137f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                        "This container does not support retaining Map.Entry objects");
138f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
139f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!(o instanceof Map.Entry)) {
140f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                return false;
141f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
142f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
143f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return Objects.equal(e.getKey(), colGetEntry(mIndex, 0))
144f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    && Objects.equal(e.getValue(), colGetEntry(mIndex, 1));
145f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
146f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
147f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
148f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public final int hashCode() {
149f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!mEntryValid) {
150f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                throw new IllegalStateException(
151f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                        "This container does not support retaining Map.Entry objects");
152f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
153f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            final Object key = colGetEntry(mIndex, 0);
154f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            final Object value = colGetEntry(mIndex, 1);
155f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return (key == null ? 0 : key.hashCode()) ^
156f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    (value == null ? 0 : value.hashCode());
157f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
158f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
159f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
160f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public final String toString() {
161f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return getKey() + "=" + getValue();
162f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
163f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
164f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
165f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    final class EntrySet implements Set<Map.Entry<K, V>> {
166f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
167f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean add(Map.Entry<K, V> object) {
168f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
169f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
170f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
171f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
172f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) {
173f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            int oldSize = colGetSize();
174f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            for (Map.Entry<K, V> entry : collection) {
175f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                colPut(entry.getKey(), entry.getValue());
176f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
177f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return oldSize != colGetSize();
178f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
179f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
180f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
181f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public void clear() {
182f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            colClear();
183f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
184f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
185f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
1868b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        public boolean contains(Object o) {
1878b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            if (!(o instanceof Map.Entry))
1888b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                return false;
1898b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1908b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            int index = colIndexOfKey(e.getKey());
1918b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            if (index < 0) {
1928b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                return false;
1938b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            }
1948b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            Object foundVal = colGetEntry(index, 1);
1958b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return Objects.equal(foundVal, e.getValue());
196f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
197f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
198f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
199f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean containsAll(Collection<?> collection) {
2008b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            Iterator<?> it = collection.iterator();
2018b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            while (it.hasNext()) {
2028b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                if (!contains(it.next())) {
2038b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                    return false;
2048b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                }
2058b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            }
2068b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return true;
207f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
208f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
209f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
210f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean isEmpty() {
211f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize() == 0;
212f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
213f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
214f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
215f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Iterator<Map.Entry<K, V>> iterator() {
216f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return new MapIterator();
217f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
218f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
219f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
220f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean remove(Object object) {
221f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
222f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
223f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
224f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
225f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean removeAll(Collection<?> collection) {
226f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
227f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
228f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
229f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
230f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean retainAll(Collection<?> collection) {
231f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
232f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
233f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
234f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
235f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public int size() {
236f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize();
237f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
238f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
239f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
240f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Object[] toArray() {
241f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
242f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
243f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
244f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
245f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public <T> T[] toArray(T[] array) {
246f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
247f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
2488b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
2498b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        @Override
2508b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        public boolean equals(Object object) {
2518b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return equalsSetHelper(this, object);
2528b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
2538b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
2548b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        @Override
2558b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        public int hashCode() {
2568b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            int result = 0;
2578b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
2588b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                final Object key = colGetEntry(i, 0);
2598b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                final Object value = colGetEntry(i, 1);
2608b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                result += ( (key == null ? 0 : key.hashCode()) ^
2618b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                        (value == null ? 0 : value.hashCode()) );
2628b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            }
2638b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return result;
2648b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
265f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    };
266f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
267f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    final class KeySet implements Set<K> {
268f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
269f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
270f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean add(K object) {
271f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
272f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
273f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
274f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
275f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean addAll(Collection<? extends K> collection) {
276f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
277f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
278f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
279f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
280f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public void clear() {
281f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            colClear();
282f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
283f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
284f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
285f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean contains(Object object) {
286f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colIndexOfKey(object) >= 0;
287f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
288f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
289f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
290f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean containsAll(Collection<?> collection) {
2918b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return containsAllHelper(colGetMap(), collection);
292f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
293f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
294f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
295f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean isEmpty() {
296f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize() == 0;
297f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
298f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
299f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
300f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Iterator<K> iterator() {
301f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return new ArrayIterator<K>(0);
302f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
303f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
304f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
305f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean remove(Object object) {
306f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            int index = colIndexOfKey(object);
307f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (index >= 0) {
308f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                colRemoveAt(index);
309f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                return true;
310f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
311f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return false;
312f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
313f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
314f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
315f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean removeAll(Collection<?> collection) {
316f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return removeAllHelper(colGetMap(), collection);
317f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
318f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
319f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
320f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean retainAll(Collection<?> collection) {
321f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return retainAllHelper(colGetMap(), collection);
322f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
323f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
324f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
325f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public int size() {
326f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize();
327f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
328f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
329f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
330f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Object[] toArray() {
3318fd3751be2fbe57ca16dd53527107a55d8e9825fDianne Hackborn            return toArrayHelper(0);
332f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
333f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
334f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
335f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public <T> T[] toArray(T[] array) {
3368fd3751be2fbe57ca16dd53527107a55d8e9825fDianne Hackborn            return toArrayHelper(array, 0);
337f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
3388b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
3398b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        @Override
3408b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        public boolean equals(Object object) {
3418b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return equalsSetHelper(this, object);
3428b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
3438b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
3448b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        @Override
3458b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        public int hashCode() {
3468b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            int result = 0;
3478b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            for (int i=colGetSize()-1; i>=0; i--) {
3488b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                Object obj = colGetEntry(i, 0);
3498b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                result += obj == null ? 0 : obj.hashCode();
3508b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            }
3518b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return result;
3528b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
353f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    };
354f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
355f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    final class ValuesCollection implements Collection<V> {
356f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
357f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
358f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean add(V object) {
359f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
360f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
361f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
362f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
363f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean addAll(Collection<? extends V> collection) {
364f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            throw new UnsupportedOperationException();
365f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
366f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
367f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
368f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public void clear() {
369f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            colClear();
370f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
371f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
372f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
373f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean contains(Object object) {
374f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colIndexOfValue(object) >= 0;
375f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
376f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
377f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
378f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean containsAll(Collection<?> collection) {
379f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            Iterator<?> it = collection.iterator();
380f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            while (it.hasNext()) {
381f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                if (!contains(it.next())) {
382f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    return false;
383f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                }
384f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
385f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return true;
386f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
387f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
388f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
389f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean isEmpty() {
390f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize() == 0;
391f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
392f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
393f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
394f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Iterator<V> iterator() {
395f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return new ArrayIterator<V>(1);
396f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
397f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
398f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
399f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean remove(Object object) {
400f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            int index = colIndexOfValue(object);
401f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (index >= 0) {
402f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                colRemoveAt(index);
403f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                return true;
404f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
405f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return false;
406f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
407f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
408f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
409f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean removeAll(Collection<?> collection) {
410f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            int N = colGetSize();
411f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            boolean changed = false;
412f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            for (int i=0; i<N; i++) {
413f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                Object cur = colGetEntry(i, 1);
414f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                if (collection.contains(cur)) {
415f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    colRemoveAt(i);
416f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    i--;
417f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    N--;
418f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    changed = true;
419f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                }
420f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
421f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return changed;
422f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
423f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
424f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
425f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public boolean retainAll(Collection<?> collection) {
426f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            int N = colGetSize();
427f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            boolean changed = false;
428f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            for (int i=0; i<N; i++) {
429f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                Object cur = colGetEntry(i, 1);
430f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                if (!collection.contains(cur)) {
431f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    colRemoveAt(i);
432f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    i--;
433f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    N--;
434f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                    changed = true;
435f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                }
436f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
437f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return changed;
438f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
439f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
440f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
441f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public int size() {
442f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return colGetSize();
443f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
444f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
445f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
446f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public Object[] toArray() {
447f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return toArrayHelper(1);
448f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
449f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
450f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        @Override
451f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        public <T> T[] toArray(T[] array) {
452f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            return toArrayHelper(array, 1);
453f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
454f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    };
455f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
456f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) {
457f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        Iterator<?> it = collection.iterator();
458f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        while (it.hasNext()) {
459f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!map.containsKey(it.next())) {
460f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                return false;
461f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
462f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
463f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return true;
464f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
465f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
466f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) {
467f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int oldSize = map.size();
468f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        Iterator<?> it = collection.iterator();
469f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        while (it.hasNext()) {
470f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            map.remove(it.next());
471f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
472f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return oldSize != map.size();
473f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
474f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
475f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) {
476f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        int oldSize = map.size();
477f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        Iterator<K> it = map.keySet().iterator();
478f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        while (it.hasNext()) {
479f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            if (!collection.contains(it.next())) {
480f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                it.remove();
481f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            }
482f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
483f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return oldSize != map.size();
484f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
485f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
486f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public Object[] toArrayHelper(int offset) {
487f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        final int N = colGetSize();
488f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        Object[] result = new Object[N];
489f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        for (int i=0; i<N; i++) {
490f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            result[i] = colGetEntry(i, offset);
491f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
492f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return result;
493f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
494f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
495f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public <T> T[] toArrayHelper(T[] array, int offset) {
496f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        final int N  = colGetSize();
497f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (array.length < N) {
498f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            @SuppressWarnings("unchecked") T[] newArray
499f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn                = (T[]) Array.newInstance(array.getClass().getComponentType(), N);
500f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            array = newArray;
501f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
502f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        for (int i=0; i<N; i++) {
503f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            array[i] = (T)colGetEntry(i, offset);
504f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
505f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (array.length > N) {
506f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            array[N] = null;
507f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
508f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return array;
509f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
510f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
5118b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn    public static <T> boolean equalsSetHelper(Set<T> set, Object object) {
5128b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        if (set == object) {
5138b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            return true;
5148b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
5158b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        if (object instanceof Set) {
5168b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            Set<?> s = (Set<?>) object;
5178b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
5188b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            try {
5198b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                return set.size() == s.size() && set.containsAll(s);
5208b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            } catch (NullPointerException ignored) {
5218b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                return false;
5228b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            } catch (ClassCastException ignored) {
5238b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn                return false;
5248b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn            }
5258b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        }
5268b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn        return false;
5278b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn    }
5288b7bc13e217034e0ddd00f9033463190f50dce88Dianne Hackborn
529f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public Set<Map.Entry<K, V>> getEntrySet() {
530f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (mEntrySet == null) {
531f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mEntrySet = new EntrySet();
532f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
533f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return mEntrySet;
534f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
535f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
536f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public Set<K> getKeySet() {
537f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (mKeySet == null) {
538f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mKeySet = new KeySet();
539f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
540f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return mKeySet;
541f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
542f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
543f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    public Collection<V> getValues() {
544f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        if (mValues == null) {
545f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn            mValues = new ValuesCollection();
546f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        }
547f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn        return mValues;
548f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    }
549f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn
550f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract int colGetSize();
551f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract Object colGetEntry(int index, int offset);
552f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract int colIndexOfKey(Object key);
553f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract int colIndexOfValue(Object key);
554f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract Map<K, V> colGetMap();
555f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract void colPut(K key, V value);
556f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract V colSetValue(int index, V value);
557f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract void colRemoveAt(int index);
558f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn    protected abstract void colClear();
559f4bf0ae2a7c2d9d92c5c8abdb82baa53b4c9ccdaDianne Hackborn}
560