+public abstract class MutableOffsetMap<K, V> extends AbstractMap<K, V> implements Cloneable, ModifiableMapPhase<K, V> {
+ static final class Ordered<K, V> extends MutableOffsetMap<K, V> {
+ Ordered() {
+ super(new LinkedHashMap<K, V>());
+ }
+
+ Ordered(final Map<K, V> source) {
+ super(OffsetMapCache.orderedOffsets(source.keySet()), source, new LinkedHashMap<K, V>());
+ }
+
+ Ordered(final Map<K, Integer> offsets, final V[] objects) {
+ super(offsets, objects, new LinkedHashMap<K, V>());
+ }
+
+ @Override
+ Object removedObject() {
+ return REMOVED;
+ }
+
+ @Override
+ UnmodifiableMapPhase<K, V> modifiedMap(final List<K> keys, final V[] objects) {
+ return new ImmutableOffsetMap.Ordered<>(OffsetMapCache.orderedOffsets(keys), objects);
+ }
+
+ @Override
+ UnmodifiableMapPhase<K, V> unmodifiedMap(final Map<K, Integer> offsets, final V[] objects) {
+ return new ImmutableOffsetMap.Ordered<>(offsets, objects);
+ }
+
+ @Override
+ SharedSingletonMap<K, V> singletonMap() {
+ return SharedSingletonMap.orderedCopyOf(this);
+ }
+ }
+
+ static final class Unordered<K, V> extends MutableOffsetMap<K, V> {
+ Unordered() {
+ super(new HashMap<K, V>());
+ }
+
+ Unordered(final Map<K, V> source) {
+ super(OffsetMapCache.unorderedOffsets(source.keySet()), source, new HashMap<K, V>());
+ }
+
+ Unordered(final Map<K, Integer> offsets, final V[] objects) {
+ super(offsets, objects, new HashMap<K, V>());
+ }
+
+ @Override
+ Object removedObject() {
+ return null;
+ }
+
+ @Override
+ UnmodifiableMapPhase<K, V> modifiedMap(final List<K> keys, final V[] objects) {
+ final Map<K, Integer> offsets = OffsetMapCache.unorderedOffsets(keys);
+ return new ImmutableOffsetMap.Unordered<>(offsets, OffsetMapCache.adjustedArray(offsets, keys, objects));
+ }
+
+ @Override
+ UnmodifiableMapPhase<K, V> unmodifiedMap(final Map<K, Integer> offsets, final V[] objects) {
+ return new ImmutableOffsetMap.Unordered<>(offsets, objects);
+ }
+
+ @Override
+ SharedSingletonMap<K, V> singletonMap() {
+ return SharedSingletonMap.unorderedCopyOf(this);
+ }
+ }
+