@Test
  public void whenInsertDuplicatesInMultiSet_thenInserted() {
    final Multiset<String> names = HashMultiset.create();
    names.add("John");
    names.add("Adam", 3);
    names.add("John");

    assertEquals(2, names.count("John"));
    names.remove("John");
    assertEquals(1, names.count("John"));

    assertEquals(3, names.count("Adam"));
    names.remove("Adam", 2);
    assertEquals(1, names.count("Adam"));
  }
 @Override
 public int remove(Object element, int occurrences) {
   checkNonnegative(occurrences, "occurrences");
   if (occurrences == 0) {
     return count(element);
   } else {
     return contains(element) ? unfiltered.remove(element, occurrences) : 0;
   }
 }
 @Override
 public void remove() {
   checkRemove(canRemove);
   if (totalCount == 1) {
     entryIterator.remove();
   } else {
     multiset.remove(currentEntry.getElement());
   }
   totalCount--;
   canRemove = false;
 }
  /** An implementation of {@link Multiset#setCount(Object, int)}. */
  static <E> int setCountImpl(Multiset<E> self, E element, int count) {
    checkNonnegative(count, "count");

    int oldCount = self.count(element);

    int delta = count - oldCount;
    if (delta > 0) {
      self.add(element, delta);
    } else if (delta < 0) {
      self.remove(element, -delta);
    }

    return oldCount;
  }
 /**
  * For each occurrence of an element {@code e} in {@code occurrencesToRemove}, removes one
  * occurrence of {@code e} in {@code multisetToModify}.
  *
  * <p>Equivalently, this method modifies {@code multisetToModify} so that {@code
  * multisetToModify.count(e)} is set to {@code Math.max(0, multisetToModify.count(e) -
  * Iterables.frequency(occurrencesToRemove, e))}.
  *
  * <p>This is <i>not</i> the same as {@code multisetToModify.} {@link Multiset#removeAll
  * removeAll}{@code (occurrencesToRemove)}, which removes all occurrences of elements that appear
  * in {@code occurrencesToRemove}. However, this operation <i>is</i> equivalent to, albeit
  * sometimes more efficient than, the following:
  *
  * <pre>{@code
  * for (E e : occurrencesToRemove) {
  *   multisetToModify.remove(e);
  * }
  * }</pre>
  *
  * @return {@code true} if {@code multisetToModify} was changed as a result of this operation
  * @since 18.0 (present in 10.0 with a requirement that the second parameter be a {@code
  *     Multiset})
  */
 public static boolean removeOccurrences(
     Multiset<?> multisetToModify, Iterable<?> occurrencesToRemove) {
   if (occurrencesToRemove instanceof Multiset) {
     return removeOccurrences(multisetToModify, (Multiset<?>) occurrencesToRemove);
   } else {
     checkNotNull(multisetToModify);
     checkNotNull(occurrencesToRemove);
     boolean changed = false;
     for (Object o : occurrencesToRemove) {
       changed |= multisetToModify.remove(o);
     }
     return changed;
   }
 }
  /**
   * For each occurrence of an element {@code e} in {@code occurrencesToRemove}, removes one
   * occurrence of {@code e} in {@code multisetToModify}.
   *
   * <p>Equivalently, this method modifies {@code multisetToModify} so that {@code
   * multisetToModify.count(e)} is set to {@code Math.max(0, multisetToModify.count(e) -
   * occurrencesToRemove.count(e))}.
   *
   * <p>This is <i>not</i> the same as {@code multisetToModify.} {@link Multiset#removeAll
   * removeAll}{@code (occurrencesToRemove)}, which removes all occurrences of elements that appear
   * in {@code occurrencesToRemove}. However, this operation <i>is</i> equivalent to, albeit
   * sometimes more efficient than, the following:
   *
   * <pre>{@code
   * for (E e : occurrencesToRemove) {
   *   multisetToModify.remove(e);
   * }
   * }</pre>
   *
   * @return {@code true} if {@code multisetToModify} was changed as a result of this operation
   * @since 10.0 (missing in 18.0 when only the overload taking an {@code Iterable} was present)
   */
  public static boolean removeOccurrences(
      Multiset<?> multisetToModify, Multiset<?> occurrencesToRemove) {
    checkNotNull(multisetToModify);
    checkNotNull(occurrencesToRemove);

    boolean changed = false;
    Iterator<? extends Entry<?>> entryIterator = multisetToModify.entrySet().iterator();
    while (entryIterator.hasNext()) {
      Entry<?> entry = entryIterator.next();
      int removeCount = occurrencesToRemove.count(entry.getElement());
      if (removeCount >= entry.getCount()) {
        entryIterator.remove();
        changed = true;
      } else if (removeCount > 0) {
        multisetToModify.remove(entry.getElement(), removeCount);
        changed = true;
      }
    }
    return changed;
  }