1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License.
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License.
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkArgument;
20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkState;
21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.IOException;
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectInputStream;
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.ObjectOutputStream;
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.io.Serializable;
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection;
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Iterator;
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Map;
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Set;
34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable;
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * A general-purpose bimap implementation using any two backing {@code Map}
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * instances.
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Note that this class contains {@code equals()} calls that keep it from
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * supporting {@code IdentityHashMap} backing maps.
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Mike Bostock
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonabstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    implements BiMap<K, V>, Serializable {
50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient Map<K, V> delegate;
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient AbstractBiMap<V, K> inverse;
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** Package-private constructor for creating a map-backed bimap. */
55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  AbstractBiMap(Map<K, V> forward, Map<V, K> backward) {
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    setDelegates(forward, backward);
57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** Private constructor for inverse bimap. */
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private AbstractBiMap(Map<K, V> backward, AbstractBiMap<V, K> forward) {
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    delegate = backward;
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    inverse = forward;
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override protected Map<K, V> delegate() {
66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return delegate;
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Specifies the delegate maps going in each direction. Called by the
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * constructor and by subclasses during deserialization.
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  void setDelegates(Map<K, V> forward, Map<V, K> backward) {
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkState(delegate == null);
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkState(inverse == null);
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkArgument(forward.isEmpty());
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkArgument(backward.isEmpty());
78090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    checkArgument(forward != backward);
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    delegate = forward;
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    inverse = new Inverse<V, K>(backward, this);
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  void setInverse(AbstractBiMap<V, K> inverse) {
84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    this.inverse = inverse;
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Query Operations (optimizations)
88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public boolean containsValue(Object value) {
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return inverse.containsKey(value);
91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Modification Operations
94090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
95090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public V put(K key, V value) {
96090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return putInBothMaps(key, value, false);
97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public V forcePut(K key, V value) {
101090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return putInBothMaps(key, value, true);
102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private V putInBothMaps(@Nullable K key, @Nullable V value, boolean force) {
105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    boolean containedKey = containsKey(key);
106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (containedKey && Objects.equal(value, get(key))) {
107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return value;
108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (force) {
110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      inverse().remove(value);
111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    } else {
112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      checkArgument(!containsValue(value), "value already present: %s", value);
113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    V oldValue = delegate.put(key, value);
115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    updateInverseMap(key, containedKey, oldValue, value);
116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return oldValue;
117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void updateInverseMap(
120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      K key, boolean containedKey, V oldValue, V newValue) {
121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (containedKey) {
122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      removeFromInverseMap(oldValue);
123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    inverse.delegate.put(newValue, key);
125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public V remove(Object key) {
128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return containsKey(key) ? removeFromBothMaps(key) : null;
129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
131090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private V removeFromBothMaps(Object key) {
132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    V oldValue = delegate.remove(key);
133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    removeFromInverseMap(oldValue);
134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return oldValue;
135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private void removeFromInverseMap(V oldValue) {
138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    inverse.delegate.remove(oldValue);
139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Bulk Operations
142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public void putAll(Map<? extends K, ? extends V> map) {
144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      put(entry.getKey(), entry.getValue());
146090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
147090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
148090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
149090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public void clear() {
150090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    delegate.clear();
151090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    inverse.delegate.clear();
152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  // Views
155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public BiMap<V, K> inverse() {
158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return inverse;
159090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient Set<K> keySet;
162090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
163090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public Set<K> keySet() {
164090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Set<K> result = keySet;
165090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return (result == null) ? keySet = new KeySet() : result;
166090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
167090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
168090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private class KeySet extends ForwardingSet<K> {
169090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override protected Set<K> delegate() {
170090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return delegate.keySet();
171090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
172090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
173090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public void clear() {
174090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      AbstractBiMap.this.clear();
175090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
176090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
177090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean remove(Object key) {
178090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      if (!contains(key)) {
179090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        return false;
180090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
181090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      removeFromBothMaps(key);
182090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return true;
183090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
184090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
185090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean removeAll(Collection<?> keysToRemove) {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardRemoveAll(keysToRemove);
187090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
188090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
189090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean retainAll(Collection<?> keysToRetain) {
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardRetainAll(keysToRetain);
191090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
192090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
193090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Iterator<K> iterator() {
194090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      final Iterator<Entry<K, V>> iterator = delegate.entrySet().iterator();
195090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return new Iterator<K>() {
196090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        Entry<K, V> entry;
197090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
199090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        public boolean hasNext() {
200090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return iterator.hasNext();
201090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
203090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        public K next() {
204090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          entry = iterator.next();
205090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return entry.getKey();
206090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
208090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        public void remove() {
209090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          checkState(entry != null);
210090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          V value = entry.getValue();
211090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          iterator.remove();
212090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          removeFromInverseMap(value);
213090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
214090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      };
215090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
216090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
217090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
218090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient Set<V> valueSet;
219090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
220090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public Set<V> values() {
221090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /*
222090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * We can almost reuse the inverse's keySet, except we have to fix the
223090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * iteration order so that it is consistent with the forward map.
224090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
225090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Set<V> result = valueSet;
226090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return (result == null) ? valueSet = new ValueSet() : result;
227090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
228090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
229090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private class ValueSet extends ForwardingSet<V> {
230090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    final Set<V> valuesDelegate = inverse.keySet();
231090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
232090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override protected Set<V> delegate() {
233090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return valuesDelegate;
234090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
235090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
236090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Iterator<V> iterator() {
237090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      final Iterator<V> iterator = delegate.values().iterator();
238090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return new Iterator<V>() {
239090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        V valueToRemove;
240090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasNext() {
242090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return iterator.hasNext();
243090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
244090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public V next() {
246090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return valueToRemove = iterator.next();
247090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
248090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void remove() {
250090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          iterator.remove();
251090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          removeFromInverseMap(valueToRemove);
252090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
253090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      };
254090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
255090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
256090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Object[] toArray() {
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray();
258090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
259090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
260090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public <T> T[] toArray(T[] array) {
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray(array);
262090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
263090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
264090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public String toString() {
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToString();
266090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
267090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
268090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
269090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private transient Set<Entry<K, V>> entrySet;
270090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
271090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  @Override public Set<Entry<K, V>> entrySet() {
272090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Set<Entry<K, V>> result = entrySet;
273090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return (result == null) ? entrySet = new EntrySet() : result;
274090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
275090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
276090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private class EntrySet extends ForwardingSet<Entry<K, V>> {
277090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    final Set<Entry<K, V>> esDelegate = delegate.entrySet();
278090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
279090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override protected Set<Entry<K, V>> delegate() {
280090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return esDelegate;
281090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
282090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
283090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public void clear() {
284090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      AbstractBiMap.this.clear();
285090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
286090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
287090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean remove(Object object) {
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!esDelegate.contains(object)) {
289090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        return false;
290090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      }
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // safe because esDelgate.contains(object).
293090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Entry<?, ?> entry = (Entry<?, ?>) object;
294090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      inverse.delegate.remove(entry.getValue());
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      /*
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * Remove the mapping in inverse before removing from esDelegate because
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * if entry is part of esDelegate, entry might be invalidated after the
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       * mapping is removed from esDelegate.
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert       */
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      esDelegate.remove(entry);
301090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return true;
302090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
303090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
304090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Iterator<Entry<K, V>> iterator() {
305090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      final Iterator<Entry<K, V>> iterator = esDelegate.iterator();
306090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return new Iterator<Entry<K, V>>() {
307090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        Entry<K, V> entry;
308090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean hasNext() {
310090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return iterator.hasNext();
311090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
312090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Entry<K, V> next() {
314090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          entry = iterator.next();
315090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          final Entry<K, V> finalEntry = entry;
316090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
317090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          return new ForwardingMapEntry<K, V>() {
318090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            @Override protected Entry<K, V> delegate() {
319090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              return finalEntry;
320090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            }
321090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
322090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            @Override public V setValue(V value) {
323090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              // Preconditions keep the map and inverse consistent.
324090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              checkState(contains(this), "entry no longer in map");
325090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              // similar to putInBothMaps, but set via entry
326090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              if (Objects.equal(value, getValue())) {
327090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson                return value;
328090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              }
329090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              checkArgument(!containsValue(value),
330090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson                  "value already present: %s", value);
331090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              V oldValue = finalEntry.setValue(value);
332090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              checkState(Objects.equal(value, get(getKey())),
333090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson                  "entry no longer in map");
334090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              updateInverseMap(getKey(), true, oldValue, value);
335090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson              return oldValue;
336090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson            }
337090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          };
338090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
339090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void remove() {
341090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          checkState(entry != null);
342090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          V value = entry.getValue();
343090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          iterator.remove();
344090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson          removeFromInverseMap(value);
345090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        }
346090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      };
347090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
348090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
349090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    // See java.util.Collections.CheckedEntrySet for details on attacks.
350090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
351090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public Object[] toArray() {
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray();
353090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
354090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public <T> T[] toArray(T[] array) {
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardToArray(array);
356090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
357090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean contains(Object o) {
358090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return Maps.containsEntryImpl(delegate(), o);
359090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
360090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean containsAll(Collection<?> c) {
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardContainsAll(c);
362090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
363090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean removeAll(Collection<?> c) {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardRemoveAll(c);
365090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
366090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @Override public boolean retainAll(Collection<?> c) {
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return standardRetainAll(c);
368090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
369090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
370090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
371090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** The inverse of any other {@code AbstractBiMap} subclass. */
372090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static class Inverse<K, V> extends AbstractBiMap<K, V> {
373090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private Inverse(Map<K, V> backward, AbstractBiMap<V, K> forward) {
374090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      super(backward, forward);
375090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
376090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
377090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /*
378090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Serialization stores the forward bimap, the inverse of this inverse.
379090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * Deserialization calls inverse() on the forward bimap and returns that
380090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * inverse.
381090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     *
382090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * If a bimap and its inverse are serialized together, the deserialized
383090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * instances have inverse() methods that return the other.
384090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
385090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
386090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    /**
387090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     * @serialData the forward bimap
388090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson     */
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectOuputStream")
390090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private void writeObject(ObjectOutputStream stream) throws IOException {
391090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      stream.defaultWriteObject();
392090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      stream.writeObject(inverse());
393090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
394090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("java.io.ObjectInputStream")
396090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    @SuppressWarnings("unchecked") // reading data stored by writeObject
397090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private void readObject(ObjectInputStream stream)
398090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        throws IOException, ClassNotFoundException {
399090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      stream.defaultReadObject();
400090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      setInverse((AbstractBiMap<V, K>) stream.readObject());
401090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
402090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("Not needed in the emulated source.")
404090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    Object readResolve() {
405090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      return inverse().inverse();
406090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
407090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GwtIncompatible("Not needed in emulated source.")
409090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    private static final long serialVersionUID = 0;
410090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
411090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("Not needed in emulated source.")
413090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static final long serialVersionUID = 0;
414090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
415