@Test
 public void keySetEqualsAndHashCode() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3, null, null);
   Verify.assertEqualsAndHashCode(
       UnifiedSet.newSetWith("One", "Two", "Three", null), map.keySet());
 }
 @Test
 public void withoutKey() {
   MutableMapIterable<String, Integer> map = this.newMapWithKeysValues("A", 1, "B", 2);
   MutableMapIterable<String, Integer> mapWithout = map.withoutKey("B");
   Assert.assertSame(map, mapWithout);
   Verify.assertMapsEqual(UnifiedMap.newWithKeysValues("A", 1), mapWithout);
 }
 @Test
 public void clearKeySet() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
   map.keySet().clear();
   Verify.assertEmpty(map);
 }
 @Test
 public void removeObject() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
   map.remove("Two");
   Verify.assertMapsEqual(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);
 }
 @Test
 public void getIfAbsentPutWith() {
   MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "1", 2, "2", 3, "3");
   Assert.assertNull(map.get(4));
   Assert.assertEquals("4", map.getIfAbsentPutWith(4, String::valueOf, 4));
   Assert.assertEquals("3", map.getIfAbsentPutWith(3, String::valueOf, 3));
   Verify.assertContainsKeyValue(4, "4", map);
 }
  @Test
  public void add() {
    MutableMapIterable<String, Integer> map = this.newMapWithKeyValue("A", 1);

    Assert.assertEquals(Integer.valueOf(1), map.add(Tuples.pair("A", 3)));
    Assert.assertNull(map.add(Tuples.pair("B", 2)));
    Verify.assertMapsEqual(UnifiedMap.newWithKeysValues("A", 3, "B", 2), map);
  }
 @Test
 public void getIfAbsentPut() {
   MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "1", 2, "2", 3, "3");
   Assert.assertNull(map.get(4));
   Assert.assertEquals("4", map.getIfAbsentPut(4, new PassThruFunction0<>("4")));
   Assert.assertEquals("3", map.getIfAbsentPut(3, new PassThruFunction0<>("3")));
   Verify.assertContainsKeyValue(4, "4", map);
 }
 @Test
 public void withAllKeyValueArguments() {
   MutableMapIterable<String, Integer> map = this.newMapWithKeysValues("A", 1, "B", 2);
   MutableMapIterable<String, Integer> mapWith =
       map.withAllKeyValueArguments(Tuples.pair("B", 22), Tuples.pair("C", 3));
   Assert.assertSame(map, mapWith);
   Verify.assertMapsEqual(UnifiedMap.newWithKeysValues("A", 1, "B", 22, "C", 3), mapWith);
 }
 @Test
 public void withoutAllKeys() {
   MutableMapIterable<String, Integer> map = this.newMapWithKeysValues("A", 1, "B", 2, "C", 3);
   MutableMapIterable<String, Integer> mapWithout =
       map.withoutAllKeys(FastList.newListWith("A", "C"));
   Assert.assertSame(map, mapWithout);
   Verify.assertMapsEqual(UnifiedMap.newWithKeysValues("B", 2), mapWithout);
 }
 @Test
 public void keysAndValues_toString() {
   MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "1", 2, "2");
   Verify.assertContains(map.keySet().toString(), FastList.newListWith("[1, 2]", "[2, 1]"));
   Verify.assertContains(map.values().toString(), FastList.newListWith("[1, 2]", "[2, 1]"));
   Verify.assertContains(map.keysView().toString(), FastList.newListWith("[1, 2]", "[2, 1]"));
   Verify.assertContains(map.valuesView().toString(), FastList.newListWith("[1, 2]", "[2, 1]"));
 }
  @Test
  public void retainAllFromValues() {
    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertFalse(map.values().retainAll(FastList.newListWith(1, 2, 3, 4)));

    Assert.assertTrue(map.values().retainAll(FastList.newListWith(1, 3)));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);
  }
 @Test
 public void updateValue() {
   MutableMapIterable<Integer, Integer> map = this.newMap();
   Iterate.forEach(
       Interval.oneTo(1000), each -> map.updateValue(each % 10, () -> 0, integer -> integer + 1));
   Assert.assertEquals(Interval.zeroTo(9).toSet(), map.keySet());
   Assert.assertEquals(
       FastList.newList(Collections.nCopies(10, 100)), FastList.newList(map.values()));
 }
  @Test
  public void removeFromValues() {
    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertFalse(map.values().remove(4));

    Assert.assertTrue(map.values().remove(2));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);
  }
  @Test
  public void removeAllFromKeySet() {
    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertFalse(map.keySet().removeAll(FastList.newListWith("Four")));

    Assert.assertTrue(map.keySet().removeAll(FastList.newListWith("Two", "Four")));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);
  }
 @Test
 public void keySetToArray() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
   MutableList<String> expected = FastList.newListWith("One", "Two", "Three").toSortedList();
   Set<String> keySet = map.keySet();
   Assert.assertEquals(expected, FastList.newListWith(keySet.toArray()).toSortedList());
   Assert.assertEquals(
       expected, FastList.newListWith(keySet.toArray(new String[keySet.size()])).toSortedList());
 }
 @Test
 public void getIfAbsentPutWithKey() {
   MutableMapIterable<Integer, Integer> map = this.newMapWithKeysValues(1, 1, 2, 2, 3, 3);
   Assert.assertNull(map.get(4));
   Assert.assertEquals(
       Integer.valueOf(4), map.getIfAbsentPutWithKey(4, Functions.getIntegerPassThru()));
   Assert.assertEquals(
       Integer.valueOf(3), map.getIfAbsentPutWithKey(3, Functions.getIntegerPassThru()));
   Verify.assertContainsKeyValue(Integer.valueOf(4), Integer.valueOf(4), map);
 }
  @Test
  public void clear() {
    MutableMapIterable<Integer, Object> map =
        this.<Integer, Object>newMapWithKeysValues(1, "One", 2, "Two", 3, "Three");
    map.clear();
    Verify.assertEmpty(map);

    MutableMapIterable<Object, Object> map2 = this.newMap();
    map2.clear();
    Verify.assertEmpty(map2);
  }
 @Test
 public void entrySetEqualsAndHashCode() {
   MutableMapIterable<String, Integer> map =
       this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
   Verify.assertEqualsAndHashCode(
       UnifiedSet.newSetWith(
           ImmutableEntry.of("One", 1),
           ImmutableEntry.of("Two", 2),
           ImmutableEntry.of("Three", 3)),
       map.entrySet());
 }
 @Test
 public void updateValue_collisions() {
   MutableMapIterable<Integer, Integer> map = this.newMap();
   MutableList<Integer> list = Interval.oneTo(2000).toList();
   Collections.shuffle(list);
   Iterate.forEach(list, each -> map.updateValue(each % 1000, () -> 0, integer -> integer + 1));
   Assert.assertEquals(Interval.zeroTo(999).toSet(), map.keySet());
   Assert.assertEquals(
       HashBag.newBag(map.values()).toStringOfItemToCount(),
       FastList.newList(Collections.nCopies(1000, 2)),
       FastList.newList(map.values()));
 }
  @Test
  public void rehash_null_collision() {
    if (this.newMap() instanceof ConcurrentMap || this.newMap() instanceof SortedMap) {
      return;
    }
    MutableMapIterable<IntegerWithCast, String> mutableMapIterable =
        this.newMapWithKeyValue(null, null);

    for (int i = 0; i < 256; i++) {
      mutableMapIterable.put(new IntegerWithCast(i), String.valueOf(i));
    }
  }
 @Test
 public void getIfAbsentPut_block_throws() {
   MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "1", 2, "2", 3, "3");
   Verify.assertThrows(
       RuntimeException.class,
       () ->
           map.getIfAbsentPut(
               4,
               () -> {
                 throw new RuntimeException();
               }));
   Assert.assertEquals(UnifiedMap.newWithKeysValues(1, "1", 2, "2", 3, "3"), map);
 }
  @Test
  public void removeNullFromValues() {
    if (this.newMap() instanceof ConcurrentMap) {
      return;
    }

    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertFalse(map.values().remove(null));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Two", 2, "Three", 3), map);
    map.put("Four", null);
    Assert.assertTrue(map.values().remove(null));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Two", 2, "Three", 3), map);
  }
  @Test
  public void removeKey() {
    MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "1", 2, "Two");

    Assert.assertEquals("1", map.removeKey(1));
    Verify.assertSize(1, map);
    Verify.denyContainsKey(1, map);

    Assert.assertNull(map.removeKey(42));
    Verify.assertSize(1, map);

    Assert.assertEquals("Two", map.removeKey(2));
    Verify.assertEmpty(map);
  }
  @Test
  public void retainAllFromKeySet_null_collision() {
    if (this.newMap() instanceof ConcurrentMap || this.newMap() instanceof SortedMap) {
      return;
    }

    IntegerWithCast key = new IntegerWithCast(0);
    MutableMapIterable<IntegerWithCast, String> mutableMapIterable =
        this.newMapWithKeysValues(null, "Test 1", key, "Test 2");

    Assert.assertFalse(mutableMapIterable.keySet().retainAll(FastList.newListWith(key, null)));

    Assert.assertEquals(
        this.newMapWithKeysValues(null, "Test 1", key, "Test 2"), mutableMapIterable);
  }
  @Test
  public void put() {
    MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "One", 2, "Two");
    Assert.assertNull(map.put(3, "Three"));
    Assert.assertEquals(UnifiedMap.newWithKeysValues(1, "One", 2, "Two", 3, "Three"), map);

    ImmutableList<Integer> key1 = Lists.immutable.with(null);
    ImmutableList<Integer> key2 = Lists.immutable.with(null);
    Object value1 = new Object();
    Object value2 = new Object();
    MutableMapIterable<ImmutableList<Integer>, Object> map2 = this.newMapWithKeyValue(key1, value1);
    Object previousValue = map2.put(key2, value2);
    Assert.assertSame(value1, previousValue);
    Assert.assertSame(key1, map2.keysView().getFirst());
  }
  @Test
  public void putAll() {
    MutableMapIterable<Integer, String> map = this.newMapWithKeysValues(1, "One", 2, "2");
    MutableMapIterable<Integer, String> toAdd = this.newMapWithKeysValues(2, "Two", 3, "Three");

    map.putAll(toAdd);
    Verify.assertSize(3, map);
    Verify.assertContainsAllKeyValues(map, 1, "One", 2, "Two", 3, "Three");

    // Testing JDK map
    MutableMapIterable<Integer, String> map2 = this.newMapWithKeysValues(1, "One", 2, "2");
    HashMap<Integer, String> hashMaptoAdd = new HashMap<>(toAdd);
    map2.putAll(hashMaptoAdd);
    Verify.assertSize(3, map2);
    Verify.assertContainsAllKeyValues(map2, 1, "One", 2, "Two", 3, "Three");
  }
 @Test
 public void updateValueWith() {
   MutableMapIterable<Integer, Integer> map = this.newMap();
   Iterate.forEach(
       Interval.oneTo(1000),
       each ->
           map.updateValueWith(
               each % 10,
               () -> 0,
               (integer, parameter) -> {
                 Assert.assertEquals("test", parameter);
                 return integer + 1;
               },
               "test"));
   Assert.assertEquals(Interval.zeroTo(9).toSet(), map.keySet());
   Assert.assertEquals(
       FastList.newList(Collections.nCopies(10, 100)), FastList.newList(map.values()));
 }
  @Test
  public void retainAllFromEntrySet() {
    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertFalse(
        map.entrySet()
            .retainAll(
                FastList.newListWith(
                    ImmutableEntry.of("One", 1),
                    ImmutableEntry.of("Two", 2),
                    ImmutableEntry.of("Three", 3),
                    ImmutableEntry.of("Four", 4))));

    Assert.assertTrue(
        map.entrySet()
            .retainAll(
                FastList.newListWith(
                    ImmutableEntry.of("One", 1),
                    ImmutableEntry.of("Three", 3),
                    ImmutableEntry.of("Four", 4))));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);

    MutableMapIterable<Integer, Integer> integers = this.newMapWithKeysValues(1, 1, 2, 2, 3, 3);
    Integer copy = new Integer(1);
    Assert.assertTrue(integers.entrySet().retainAll(mList(ImmutableEntry.of(copy, copy))));
    Assert.assertEquals(iMap(copy, copy), integers);
    Assert.assertNotSame(copy, Iterate.getOnly(integers.entrySet()).getKey());
    Assert.assertNotSame(copy, Iterate.getOnly(integers.entrySet()).getValue());
  }
  @Test
  public void removeFromEntrySet() {
    MutableMapIterable<String, Integer> map =
        this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3);
    Assert.assertTrue(map.entrySet().remove(ImmutableEntry.of("Two", 2)));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);

    Assert.assertFalse(map.entrySet().remove(ImmutableEntry.of("Four", 4)));
    Assert.assertEquals(UnifiedMap.newWithKeysValues("One", 1, "Three", 3), map);

    Assert.assertFalse(map.entrySet().remove(null));

    MutableMapIterable<String, Integer> mapWithNullKey =
        this.newMapWithKeysValues("One", 1, null, 2, "Three", 3);
    Assert.assertTrue(
        mapWithNullKey.entrySet().remove(new ImmutableEntry<String, Integer>(null, 2)));
  }
 @Test
 public void toImmutable() {
   MutableMapIterable<Integer, String> map = this.newMapWithKeyValue(1, "One");
   ImmutableMapIterable<Integer, String> immutable = map.toImmutable();
   Assert.assertEquals(Maps.immutable.with(1, "One"), immutable);
 }