guava/src/com/google/common/collect/Multisets.java
@CanIgnoreReturnValue
  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;
    }
  }
@CanIgnoreReturnValue
  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) -
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})