11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkState;
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.CollectPreconditions.checkNonnegative;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.collect.CollectPreconditions.checkRemove;
237dd252788645e940eada959bdde927426e2531c9Paul Duffin
247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtCompatible;
257dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.GwtIncompatible;
263ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport com.google.common.base.MoreObjects;
277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.primitives.Ints;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectInputStream;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.ObjectOutputStream;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ConcurrentModificationException;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.NoSuchElementException;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
417dd252788645e940eada959bdde927426e2531c9Paul Duffin * A multiset which maintains the ordering of its elements, according to either their natural order
427dd252788645e940eada959bdde927426e2531c9Paul Duffin * or an explicit {@link Comparator}. In all cases, this implementation uses
437dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link Comparable#compareTo} or {@link Comparator#compare} instead of {@link Object#equals} to
447dd252788645e940eada959bdde927426e2531c9Paul Duffin * determine equivalence of instances.
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
467dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p><b>Warning:</b> The comparison must be <i>consistent with equals</i> as explained by the
477dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link Comparable} class specification. Otherwise, the resulting multiset will violate the
487dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@link java.util.Collection} contract, which is specified in terms of {@link Object#equals}.
497dd252788645e940eada959bdde927426e2531c9Paul Duffin *
507dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>See the Guava User Guide article on <a href=
517dd252788645e940eada959bdde927426e2531c9Paul Duffin * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
527dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code Multiset}</a>.
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
597dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements Serializable {
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
627dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Creates a new, empty multiset, sorted according to the elements' natural order. All elements
637dd252788645e940eada959bdde927426e2531c9Paul Duffin   * inserted into the multiset must implement the {@code Comparable} interface. Furthermore, all
647dd252788645e940eada959bdde927426e2531c9Paul Duffin   * such elements must be <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
657dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code ClassCastException} for any elements {@code e1} and {@code e2} in the multiset. If the
667dd252788645e940eada959bdde927426e2531c9Paul Duffin   * user attempts to add an element to the multiset that violates this constraint (for example,
677dd252788645e940eada959bdde927426e2531c9Paul Duffin   * the user attempts to add a string element to a set whose elements are integers), the
687dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code add(Object)} call will throw a {@code ClassCastException}.
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
707dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
717dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <E extends Comparable> TreeMultiset<E> create() {
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new TreeMultiset<E>(Ordering.natural());
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
787dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Creates a new, empty multiset, sorted according to the specified comparator. All elements
797dd252788645e940eada959bdde927426e2531c9Paul Duffin   * inserted into the multiset must be <i>mutually comparable</i> by the specified comparator:
807dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code comparator.compare(e1,
817dd252788645e940eada959bdde927426e2531c9Paul Duffin   * e2)} must not throw a {@code ClassCastException} for any elements {@code e1} and {@code e2} in
827dd252788645e940eada959bdde927426e2531c9Paul Duffin   * the multiset. If the user attempts to add an element to the multiset that violates this
837dd252788645e940eada959bdde927426e2531c9Paul Duffin   * constraint, the {@code add(Object)} call will throw a {@code ClassCastException}.
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
857dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param comparator
867dd252788645e940eada959bdde927426e2531c9Paul Duffin   *          the comparator that will be used to sort this multiset. A null value indicates that
877dd252788645e940eada959bdde927426e2531c9Paul Duffin   *          the elements' <i>natural ordering</i> should be used.
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked")
907dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static <E> TreeMultiset<E> create(@Nullable Comparator<? super E> comparator) {
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return (comparator == null)
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ? new TreeMultiset<E>((Comparator) Ordering.natural())
937dd252788645e940eada959bdde927426e2531c9Paul Duffin        : new TreeMultiset<E>(comparator);
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
977dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Creates an empty multiset containing the given initial elements, sorted according to the
987dd252788645e940eada959bdde927426e2531c9Paul Duffin   * elements' natural order.
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>This implementation is highly efficient when {@code elements} is itself a {@link Multiset}.
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1027dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
1037dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static <E extends Comparable> TreeMultiset<E> create(Iterable<? extends E> elements) {
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TreeMultiset<E> multiset = create();
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterables.addAll(multiset, elements);
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return multiset;
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1117dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final transient Reference<AvlNode<E>> rootReference;
1127dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final transient GeneralRange<E> range;
1137dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final transient AvlNode<E> header;
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin
1157dd252788645e940eada959bdde927426e2531c9Paul Duffin  TreeMultiset(Reference<AvlNode<E>> rootReference, GeneralRange<E> range, AvlNode<E> endLink) {
1167dd252788645e940eada959bdde927426e2531c9Paul Duffin    super(range.comparator());
1177dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.rootReference = rootReference;
1187dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.range = range;
1197dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.header = endLink;
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin  TreeMultiset(Comparator<? super E> comparator) {
1233c77433663281544363151bf284b0240dfd22a42Paul Duffin    super(comparator);
1243c77433663281544363151bf284b0240dfd22a42Paul Duffin    this.range = GeneralRange.all(comparator);
1257dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.header = new AvlNode<E>(null, 1);
1267dd252788645e940eada959bdde927426e2531c9Paul Duffin    successor(header, header);
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.rootReference = new Reference<AvlNode<E>>();
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin   * A function which can be summed across a subtree.
1327dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin  private enum Aggregate {
1347dd252788645e940eada959bdde927426e2531c9Paul Duffin    SIZE {
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
1367dd252788645e940eada959bdde927426e2531c9Paul Duffin      int nodeAggregate(AvlNode<?> node) {
1377dd252788645e940eada959bdde927426e2531c9Paul Duffin        return node.elemCount;
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin      long treeAggregate(@Nullable AvlNode<?> root) {
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (root == null) ? 0 : root.totalCount;
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin    },
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin    DISTINCT {
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin      int nodeAggregate(AvlNode<?> node) {
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin        return 1;
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
1527dd252788645e940eada959bdde927426e2531c9Paul Duffin      long treeAggregate(@Nullable AvlNode<?> root) {
1537dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (root == null) ? 0 : root.distinctElements;
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1557dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
1567dd252788645e940eada959bdde927426e2531c9Paul Duffin    abstract int nodeAggregate(AvlNode<?> node);
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1587dd252788645e940eada959bdde927426e2531c9Paul Duffin    abstract long treeAggregate(@Nullable AvlNode<?> root);
1597dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin  private long aggregateForEntries(Aggregate aggr) {
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin    long total = aggr.treeAggregate(root);
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (range.hasLowerBound()) {
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin      total -= aggregateBelowRange(aggr, root);
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (range.hasUpperBound()) {
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin      total -= aggregateAboveRange(aggr, root);
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin    return total;
1717dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1737dd252788645e940eada959bdde927426e2531c9Paul Duffin  private long aggregateBelowRange(Aggregate aggr, @Nullable AvlNode<E> node) {
1747dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (node == null) {
1757dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
1767dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1777dd252788645e940eada959bdde927426e2531c9Paul Duffin    int cmp = comparator().compare(range.getLowerEndpoint(), node.elem);
1787dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (cmp < 0) {
1797dd252788645e940eada959bdde927426e2531c9Paul Duffin      return aggregateBelowRange(aggr, node.left);
1807dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (cmp == 0) {
1817dd252788645e940eada959bdde927426e2531c9Paul Duffin      switch (range.getLowerBoundType()) {
1827dd252788645e940eada959bdde927426e2531c9Paul Duffin        case OPEN:
1837dd252788645e940eada959bdde927426e2531c9Paul Duffin          return aggr.nodeAggregate(node) + aggr.treeAggregate(node.left);
1847dd252788645e940eada959bdde927426e2531c9Paul Duffin        case CLOSED:
1857dd252788645e940eada959bdde927426e2531c9Paul Duffin          return aggr.treeAggregate(node.left);
1867dd252788645e940eada959bdde927426e2531c9Paul Duffin        default:
1877dd252788645e940eada959bdde927426e2531c9Paul Duffin          throw new AssertionError();
1887dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1897dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
1907dd252788645e940eada959bdde927426e2531c9Paul Duffin      return aggr.treeAggregate(node.left) + aggr.nodeAggregate(node)
1917dd252788645e940eada959bdde927426e2531c9Paul Duffin          + aggregateBelowRange(aggr, node.right);
1923c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
1937dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
194dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
1957dd252788645e940eada959bdde927426e2531c9Paul Duffin  private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode<E> node) {
1967dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (node == null) {
1977dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
1987dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1997dd252788645e940eada959bdde927426e2531c9Paul Duffin    int cmp = comparator().compare(range.getUpperEndpoint(), node.elem);
2007dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (cmp > 0) {
2017dd252788645e940eada959bdde927426e2531c9Paul Duffin      return aggregateAboveRange(aggr, node.right);
2027dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (cmp == 0) {
2037dd252788645e940eada959bdde927426e2531c9Paul Duffin      switch (range.getUpperBoundType()) {
2047dd252788645e940eada959bdde927426e2531c9Paul Duffin        case OPEN:
2057dd252788645e940eada959bdde927426e2531c9Paul Duffin          return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right);
2067dd252788645e940eada959bdde927426e2531c9Paul Duffin        case CLOSED:
2077dd252788645e940eada959bdde927426e2531c9Paul Duffin          return aggr.treeAggregate(node.right);
2087dd252788645e940eada959bdde927426e2531c9Paul Duffin        default:
2097dd252788645e940eada959bdde927426e2531c9Paul Duffin          throw new AssertionError();
2103c77433663281544363151bf284b0240dfd22a42Paul Duffin      }
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
2127dd252788645e940eada959bdde927426e2531c9Paul Duffin      return aggr.treeAggregate(node.right) + aggr.nodeAggregate(node)
2137dd252788645e940eada959bdde927426e2531c9Paul Duffin          + aggregateAboveRange(aggr, node.left);
2143c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
2187dd252788645e940eada959bdde927426e2531c9Paul Duffin  public int size() {
2197dd252788645e940eada959bdde927426e2531c9Paul Duffin    return Ints.saturatedCast(aggregateForEntries(Aggregate.SIZE));
2203c77433663281544363151bf284b0240dfd22a42Paul Duffin  }
2213c77433663281544363151bf284b0240dfd22a42Paul Duffin
2223c77433663281544363151bf284b0240dfd22a42Paul Duffin  @Override
2237dd252788645e940eada959bdde927426e2531c9Paul Duffin  int distinctElements() {
2247dd252788645e940eada959bdde927426e2531c9Paul Duffin    return Ints.saturatedCast(aggregateForEntries(Aggregate.DISTINCT));
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int count(@Nullable Object element) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2307dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked")
2317dd252788645e940eada959bdde927426e2531c9Paul Duffin      E e = (E) element;
2327dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> root = rootReference.get();
2337dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!range.contains(e) || root == null) {
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin        return 0;
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin      return root.count(comparator(), e);
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ClassCastException e) {
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 0;
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException e) {
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 0;
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
2457dd252788645e940eada959bdde927426e2531c9Paul Duffin  public int add(@Nullable E element, int occurrences) {
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNonnegative(occurrences, "occurrences");
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (occurrences == 0) {
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return count(element);
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkArgument(range.contains(element));
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
2527dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (root == null) {
2537dd252788645e940eada959bdde927426e2531c9Paul Duffin      comparator().compare(element, element);
2547dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> newRoot = new AvlNode<E>(element, occurrences);
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin      successor(header, newRoot, header);
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin      rootReference.checkAndSet(root, newRoot);
2577dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2597dd252788645e940eada959bdde927426e2531c9Paul Duffin    int[] result = new int[1]; // used as a mutable int reference to hold result
2607dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> newRoot = root.add(comparator(), element, occurrences, result);
2617dd252788645e940eada959bdde927426e2531c9Paul Duffin    rootReference.checkAndSet(root, newRoot);
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result[0];
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int remove(@Nullable Object element, int occurrences) {
2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNonnegative(occurrences, "occurrences");
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (occurrences == 0) {
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return count(element);
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin    int[] result = new int[1]; // used as a mutable int reference to hold result
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> newRoot;
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin      @SuppressWarnings("unchecked")
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin      E e = (E) element;
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!range.contains(e) || root == null) {
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin        return 0;
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin      newRoot = root.remove(comparator(), e, occurrences, result);
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (ClassCastException e) {
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 0;
2837dd252788645e940eada959bdde927426e2531c9Paul Duffin    } catch (NullPointerException e) {
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin    rootReference.checkAndSet(root, newRoot);
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result[0];
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
2917dd252788645e940eada959bdde927426e2531c9Paul Duffin  public int setCount(@Nullable E element, int count) {
2920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNonnegative(count, "count");
2937dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (!range.contains(element)) {
2947dd252788645e940eada959bdde927426e2531c9Paul Duffin      checkArgument(count == 0);
2957dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
2967dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin
2987dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
2997dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (root == null) {
3007dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (count > 0) {
3017dd252788645e940eada959bdde927426e2531c9Paul Duffin        add(element, count);
3027dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3037dd252788645e940eada959bdde927426e2531c9Paul Duffin      return 0;
3047dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3057dd252788645e940eada959bdde927426e2531c9Paul Duffin    int[] result = new int[1]; // used as a mutable int reference to hold result
3067dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> newRoot = root.setCount(comparator(), element, count, result);
3077dd252788645e940eada959bdde927426e2531c9Paul Duffin    rootReference.checkAndSet(root, newRoot);
3087dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result[0];
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin  public boolean setCount(@Nullable E element, int oldCount, int newCount) {
3130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNonnegative(newCount, "newCount");
3140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNonnegative(oldCount, "oldCount");
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkArgument(range.contains(element));
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (root == null) {
3197dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (oldCount == 0) {
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (newCount > 0) {
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin          add(element, newCount);
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
3237dd252788645e940eada959bdde927426e2531c9Paul Duffin        return true;
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin        return false;
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin    int[] result = new int[1]; // used as a mutable int reference to hold result
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> newRoot = root.setCount(comparator(), element, oldCount, newCount, result);
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin    rootReference.checkAndSet(root, newRoot);
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result[0] == oldCount;
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin  private Entry<E> wrapEntry(final AvlNode<E> baseEntry) {
3357dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new Multisets.AbstractEntry<E>() {
3360888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
3377dd252788645e940eada959bdde927426e2531c9Paul Duffin      public E getElement() {
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin        return baseEntry.getElement();
3397dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3407dd252788645e940eada959bdde927426e2531c9Paul Duffin
3410888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
3427dd252788645e940eada959bdde927426e2531c9Paul Duffin      public int getCount() {
3437dd252788645e940eada959bdde927426e2531c9Paul Duffin        int result = baseEntry.getCount();
3447dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result == 0) {
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin          return count(getElement());
3467dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else {
3477dd252788645e940eada959bdde927426e2531c9Paul Duffin          return result;
3487dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
3497dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3507dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3537dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3547dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the first node in the tree that is in range.
3557dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable private AvlNode<E> firstNode() {
3577dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
3587dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (root == null) {
3597dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
3607dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3617dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> node;
3627dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (range.hasLowerBound()) {
3637dd252788645e940eada959bdde927426e2531c9Paul Duffin      E endpoint = range.getLowerEndpoint();
3647dd252788645e940eada959bdde927426e2531c9Paul Duffin      node = rootReference.get().ceiling(comparator(), endpoint);
3657dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (node == null) {
3667dd252788645e940eada959bdde927426e2531c9Paul Duffin        return null;
3677dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3687dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (range.getLowerBoundType() == BoundType.OPEN
3697dd252788645e940eada959bdde927426e2531c9Paul Duffin          && comparator().compare(endpoint, node.getElement()) == 0) {
3707dd252788645e940eada959bdde927426e2531c9Paul Duffin        node = node.succ;
3717dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3727dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
3737dd252788645e940eada959bdde927426e2531c9Paul Duffin      node = header.succ;
3747dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3757dd252788645e940eada959bdde927426e2531c9Paul Duffin    return (node == header || !range.contains(node.getElement())) ? null : node;
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable private AvlNode<E> lastNode() {
3797dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> root = rootReference.get();
3807dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (root == null) {
3817dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
3827dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3837dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> node;
3847dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (range.hasUpperBound()) {
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin      E endpoint = range.getUpperEndpoint();
3867dd252788645e940eada959bdde927426e2531c9Paul Duffin      node = rootReference.get().floor(comparator(), endpoint);
3877dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (node == null) {
3887dd252788645e940eada959bdde927426e2531c9Paul Duffin        return null;
3897dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3907dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (range.getUpperBoundType() == BoundType.OPEN
3917dd252788645e940eada959bdde927426e2531c9Paul Duffin          && comparator().compare(endpoint, node.getElement()) == 0) {
3927dd252788645e940eada959bdde927426e2531c9Paul Duffin        node = node.pred;
3937dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
3957dd252788645e940eada959bdde927426e2531c9Paul Duffin      node = header.pred;
3967dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3977dd252788645e940eada959bdde927426e2531c9Paul Duffin    return (node == header || !range.contains(node.getElement())) ? null : node;
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4007dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
4017dd252788645e940eada959bdde927426e2531c9Paul Duffin  Iterator<Entry<E>> entryIterator() {
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new Iterator<Entry<E>>() {
4037dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> current = firstNode();
4047dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<E> prevEntry;
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public boolean hasNext() {
4087dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (current == null) {
4097dd252788645e940eada959bdde927426e2531c9Paul Duffin          return false;
4107dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else if (range.tooHigh(current.getElement())) {
4117dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = null;
4127dd252788645e940eada959bdde927426e2531c9Paul Duffin          return false;
4137dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else {
4147dd252788645e940eada959bdde927426e2531c9Paul Duffin          return true;
4157dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public Entry<E> next() {
4207dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (!hasNext()) {
4217dd252788645e940eada959bdde927426e2531c9Paul Duffin          throw new NoSuchElementException();
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4237dd252788645e940eada959bdde927426e2531c9Paul Duffin        Entry<E> result = wrapEntry(current);
4247dd252788645e940eada959bdde927426e2531c9Paul Duffin        prevEntry = result;
4257dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (current.succ == header) {
4267dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = null;
4277dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else {
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = current.succ;
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin        return result;
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public void remove() {
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        checkRemove(prevEntry != null);
4367dd252788645e940eada959bdde927426e2531c9Paul Duffin        setCount(prevEntry.getElement(), 0);
4377dd252788645e940eada959bdde927426e2531c9Paul Duffin        prevEntry = null;
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    };
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4427dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Override
4437dd252788645e940eada959bdde927426e2531c9Paul Duffin  Iterator<Entry<E>> descendingEntryIterator() {
4447dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new Iterator<Entry<E>>() {
4457dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> current = lastNode();
4467dd252788645e940eada959bdde927426e2531c9Paul Duffin      Entry<E> prevEntry = null;
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4497dd252788645e940eada959bdde927426e2531c9Paul Duffin      public boolean hasNext() {
4507dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (current == null) {
4517dd252788645e940eada959bdde927426e2531c9Paul Duffin          return false;
4527dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else if (range.tooLow(current.getElement())) {
4537dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = null;
4547dd252788645e940eada959bdde927426e2531c9Paul Duffin          return false;
4557dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else {
4567dd252788645e940eada959bdde927426e2531c9Paul Duffin          return true;
4577dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4587dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4617dd252788645e940eada959bdde927426e2531c9Paul Duffin      public Entry<E> next() {
4627dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (!hasNext()) {
4637dd252788645e940eada959bdde927426e2531c9Paul Duffin          throw new NoSuchElementException();
4647dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4657dd252788645e940eada959bdde927426e2531c9Paul Duffin        Entry<E> result = wrapEntry(current);
4667dd252788645e940eada959bdde927426e2531c9Paul Duffin        prevEntry = result;
4677dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (current.pred == header) {
4687dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = null;
4697dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else {
4707dd252788645e940eada959bdde927426e2531c9Paul Duffin          current = current.pred;
4717dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
4727dd252788645e940eada959bdde927426e2531c9Paul Duffin        return result;
4737dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override
4767dd252788645e940eada959bdde927426e2531c9Paul Duffin      public void remove() {
4770888a09821a98ac0680fad765217302858e70fa4Paul Duffin        checkRemove(prevEntry != null);
4787dd252788645e940eada959bdde927426e2531c9Paul Duffin        setCount(prevEntry.getElement(), 0);
4797dd252788645e940eada959bdde927426e2531c9Paul Duffin        prevEntry = null;
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4817dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4840888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
4857dd252788645e940eada959bdde927426e2531c9Paul Duffin  public SortedMultiset<E> headMultiset(@Nullable E upperBound, BoundType boundType) {
4860888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.upTo(
4870888a09821a98ac0680fad765217302858e70fa4Paul Duffin        comparator(),
4880888a09821a98ac0680fad765217302858e70fa4Paul Duffin        upperBound,
4890888a09821a98ac0680fad765217302858e70fa4Paul Duffin        boundType)), header);
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4920888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
4937dd252788645e940eada959bdde927426e2531c9Paul Duffin  public SortedMultiset<E> tailMultiset(@Nullable E lowerBound, BoundType boundType) {
4940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.downTo(
4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin        comparator(),
4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        lowerBound,
4970888a09821a98ac0680fad765217302858e70fa4Paul Duffin        boundType)), header);
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5007dd252788645e940eada959bdde927426e2531c9Paul Duffin  static int distinctElements(@Nullable AvlNode<?> node) {
5017dd252788645e940eada959bdde927426e2531c9Paul Duffin    return (node == null) ? 0 : node.distinctElements;
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5047dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final class Reference<T> {
5050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable private T value;
5067dd252788645e940eada959bdde927426e2531c9Paul Duffin
5070888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable public T get() {
5087dd252788645e940eada959bdde927426e2531c9Paul Duffin      return value;
5097dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5107dd252788645e940eada959bdde927426e2531c9Paul Duffin
5117dd252788645e940eada959bdde927426e2531c9Paul Duffin    public void checkAndSet(@Nullable T expected, T newValue) {
5127dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (value != expected) {
5137dd252788645e940eada959bdde927426e2531c9Paul Duffin        throw new ConcurrentModificationException();
5147dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5157dd252788645e940eada959bdde927426e2531c9Paul Duffin      value = newValue;
5167dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5197dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final class AvlNode<E> extends Multisets.AbstractEntry<E> {
5200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable private final E elem;
5217dd252788645e940eada959bdde927426e2531c9Paul Duffin
5227dd252788645e940eada959bdde927426e2531c9Paul Duffin    // elemCount is 0 iff this node has been deleted.
5237dd252788645e940eada959bdde927426e2531c9Paul Duffin    private int elemCount;
5247dd252788645e940eada959bdde927426e2531c9Paul Duffin
5257dd252788645e940eada959bdde927426e2531c9Paul Duffin    private int distinctElements;
5267dd252788645e940eada959bdde927426e2531c9Paul Duffin    private long totalCount;
5277dd252788645e940eada959bdde927426e2531c9Paul Duffin    private int height;
5287dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> left;
5297dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> right;
5307dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> pred;
5317dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> succ;
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5337dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode(@Nullable E elem, int elemCount) {
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkArgument(elemCount > 0);
5357dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.elem = elem;
5367dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.elemCount = elemCount;
5377dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.totalCount = elemCount;
5387dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.distinctElements = 1;
5397dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.height = 1;
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.left = null;
5417dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.right = null;
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5447dd252788645e940eada959bdde927426e2531c9Paul Duffin    public int count(Comparator<? super E> comparator, E e) {
5457dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
5467dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
5477dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (left == null) ? 0 : left.count(comparator, e);
5487dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp > 0) {
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (right == null) ? 0 : right.count(comparator, e);
5507dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
5517dd252788645e940eada959bdde927426e2531c9Paul Duffin        return elemCount;
5527dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5557dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> addRightChild(E e, int count) {
5567dd252788645e940eada959bdde927426e2531c9Paul Duffin      right = new AvlNode<E>(e, count);
5577dd252788645e940eada959bdde927426e2531c9Paul Duffin      successor(this, right, succ);
5587dd252788645e940eada959bdde927426e2531c9Paul Duffin      height = Math.max(2, height);
5597dd252788645e940eada959bdde927426e2531c9Paul Duffin      distinctElements++;
5607dd252788645e940eada959bdde927426e2531c9Paul Duffin      totalCount += count;
5617dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5647dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> addLeftChild(E e, int count) {
5657dd252788645e940eada959bdde927426e2531c9Paul Duffin      left = new AvlNode<E>(e, count);
5667dd252788645e940eada959bdde927426e2531c9Paul Duffin      successor(pred, left, this);
5677dd252788645e940eada959bdde927426e2531c9Paul Duffin      height = Math.max(2, height);
5687dd252788645e940eada959bdde927426e2531c9Paul Duffin      distinctElements++;
5697dd252788645e940eada959bdde927426e2531c9Paul Duffin      totalCount += count;
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
5717dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5723c77433663281544363151bf284b0240dfd22a42Paul Duffin
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> add(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin      /*
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin       * It speeds things up considerably to unconditionally add count to totalCount here,
5767dd252788645e940eada959bdde927426e2531c9Paul Duffin       * but that destroys failure atomicity in the case of count overflow. =(
5777dd252788645e940eada959bdde927426e2531c9Paul Duffin       */
5787dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
5797dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
5807dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initLeft = left;
5817dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initLeft == null) {
5827dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
5837dd252788645e940eada959bdde927426e2531c9Paul Duffin          return addLeftChild(e, count);
5847dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
5857dd252788645e940eada959bdde927426e2531c9Paul Duffin        int initHeight = initLeft.height;
5863c77433663281544363151bf284b0240dfd22a42Paul Duffin
5877dd252788645e940eada959bdde927426e2531c9Paul Duffin        left = initLeft.add(comparator, e, count, result);
5887dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] == 0) {
5897dd252788645e940eada959bdde927426e2531c9Paul Duffin          distinctElements++;
5907dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
5917dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount += count;
5927dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (left.height == initHeight) ? this : rebalance();
5937dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp > 0) {
5947dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initRight = right;
5957dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initRight == null) {
5967dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
5977dd252788645e940eada959bdde927426e2531c9Paul Duffin          return addRightChild(e, count);
5987dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
5997dd252788645e940eada959bdde927426e2531c9Paul Duffin        int initHeight = initRight.height;
6003c77433663281544363151bf284b0240dfd22a42Paul Duffin
6017dd252788645e940eada959bdde927426e2531c9Paul Duffin        right = initRight.add(comparator, e, count, result);
6027dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] == 0) {
6037dd252788645e940eada959bdde927426e2531c9Paul Duffin          distinctElements++;
6047dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6057dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount += count;
6067dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (right.height == initHeight) ? this : rebalance();
6077dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6083c77433663281544363151bf284b0240dfd22a42Paul Duffin
6097dd252788645e940eada959bdde927426e2531c9Paul Duffin      // adding count to me!  No rebalance possible.
6107dd252788645e940eada959bdde927426e2531c9Paul Duffin      result[0] = elemCount;
6117dd252788645e940eada959bdde927426e2531c9Paul Duffin      long resultCount = (long) elemCount + count;
6127dd252788645e940eada959bdde927426e2531c9Paul Duffin      checkArgument(resultCount <= Integer.MAX_VALUE);
6137dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.elemCount += count;
6147dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.totalCount += count;
6157dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6187dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> remove(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
6197dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
6207dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
6217dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initLeft = left;
6227dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initLeft == null) {
6237dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
6247dd252788645e940eada959bdde927426e2531c9Paul Duffin          return this;
6257dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin        left = initLeft.remove(comparator, e, count, result);
6287dd252788645e940eada959bdde927426e2531c9Paul Duffin
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] > 0) {
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (count >= result[0]) {
6317dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements--;
6327dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.totalCount -= result[0];
6337dd252788645e940eada959bdde927426e2531c9Paul Duffin          } else {
6347dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.totalCount -= count;
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (result[0] == 0) ? this : rebalance();
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp > 0) {
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initRight = right;
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initRight == null) {
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin          return this;
6437dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin        right = initRight.remove(comparator, e, count, result);
6467dd252788645e940eada959bdde927426e2531c9Paul Duffin
6477dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] > 0) {
6487dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (count >= result[0]) {
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements--;
6507dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.totalCount -= result[0];
6517dd252788645e940eada959bdde927426e2531c9Paul Duffin          } else {
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.totalCount -= count;
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
6547dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6577dd252788645e940eada959bdde927426e2531c9Paul Duffin
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin      // removing count from me!
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin      result[0] = elemCount;
6607dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (count >= elemCount) {
6617dd252788645e940eada959bdde927426e2531c9Paul Duffin        return deleteMe();
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
6637dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.elemCount -= count;
6647dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount -= count;
6657dd252788645e940eada959bdde927426e2531c9Paul Duffin        return this;
6667dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6673c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
6683c77433663281544363151bf284b0240dfd22a42Paul Duffin
6697dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> setCount(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
6727dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initLeft = left;
6737dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initLeft == null) {
6747dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin          return (count > 0) ? addLeftChild(e, count) : this;
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
6773c77433663281544363151bf284b0240dfd22a42Paul Duffin
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin        left = initLeft.setCount(comparator, e, count, result);
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (count == 0 && result[0] != 0) {
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.distinctElements--;
6827dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else if (count > 0 && result[0] == 0) {
6837dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.distinctElements++;
6843c77433663281544363151bf284b0240dfd22a42Paul Duffin        }
6853c77433663281544363151bf284b0240dfd22a42Paul Duffin
6867dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount += count - result[0];
6877dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
6887dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp > 0) {
6897dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initRight = right;
6907dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initRight == null) {
6917dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
6927dd252788645e940eada959bdde927426e2531c9Paul Duffin          return (count > 0) ? addRightChild(e, count) : this;
6933c77433663281544363151bf284b0240dfd22a42Paul Duffin        }
6943c77433663281544363151bf284b0240dfd22a42Paul Duffin
6957dd252788645e940eada959bdde927426e2531c9Paul Duffin        right = initRight.setCount(comparator, e, count, result);
6963c77433663281544363151bf284b0240dfd22a42Paul Duffin
6977dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (count == 0 && result[0] != 0) {
6987dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.distinctElements--;
6997dd252788645e940eada959bdde927426e2531c9Paul Duffin        } else if (count > 0 && result[0] == 0) {
7007dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.distinctElements++;
701dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin        }
7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7037dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount += count - result[0];
7047dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
7057dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7077dd252788645e940eada959bdde927426e2531c9Paul Duffin      // setting my count
7087dd252788645e940eada959bdde927426e2531c9Paul Duffin      result[0] = elemCount;
7097dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (count == 0) {
7107dd252788645e940eada959bdde927426e2531c9Paul Duffin        return deleteMe();
7117dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7127dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.totalCount += count - elemCount;
7137dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.elemCount = count;
7147dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
7157dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7167dd252788645e940eada959bdde927426e2531c9Paul Duffin
7170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    AvlNode<E> setCount(
7180888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Comparator<? super E> comparator,
7190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Nullable E e,
7200888a09821a98ac0680fad765217302858e70fa4Paul Duffin        int expectedCount,
7210888a09821a98ac0680fad765217302858e70fa4Paul Duffin        int newCount,
7220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        int[] result) {
7237dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
7247dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
7257dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initLeft = left;
7267dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initLeft == null) {
7277dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
7287dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (expectedCount == 0 && newCount > 0) {
7297dd252788645e940eada959bdde927426e2531c9Paul Duffin            return addLeftChild(e, newCount);
7307dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
7317dd252788645e940eada959bdde927426e2531c9Paul Duffin          return this;
7327dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
7337dd252788645e940eada959bdde927426e2531c9Paul Duffin
7347dd252788645e940eada959bdde927426e2531c9Paul Duffin        left = initLeft.setCount(comparator, e, expectedCount, newCount, result);
7357dd252788645e940eada959bdde927426e2531c9Paul Duffin
7367dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] == expectedCount) {
7377dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (newCount == 0 && result[0] != 0) {
7387dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements--;
7397dd252788645e940eada959bdde927426e2531c9Paul Duffin          } else if (newCount > 0 && result[0] == 0) {
7407dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements++;
7417dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
7427dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.totalCount += newCount - result[0];
7437dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
7447dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
7457dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp > 0) {
7467dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> initRight = right;
7477dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (initRight == null) {
7487dd252788645e940eada959bdde927426e2531c9Paul Duffin          result[0] = 0;
7497dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (expectedCount == 0 && newCount > 0) {
7507dd252788645e940eada959bdde927426e2531c9Paul Duffin            return addRightChild(e, newCount);
7517dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
7527dd252788645e940eada959bdde927426e2531c9Paul Duffin          return this;
7537dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
7547dd252788645e940eada959bdde927426e2531c9Paul Duffin
7557dd252788645e940eada959bdde927426e2531c9Paul Duffin        right = initRight.setCount(comparator, e, expectedCount, newCount, result);
7567dd252788645e940eada959bdde927426e2531c9Paul Duffin
7577dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (result[0] == expectedCount) {
7587dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (newCount == 0 && result[0] != 0) {
7597dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements--;
7607dd252788645e940eada959bdde927426e2531c9Paul Duffin          } else if (newCount > 0 && result[0] == 0) {
7617dd252788645e940eada959bdde927426e2531c9Paul Duffin            this.distinctElements++;
7627dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
7637dd252788645e940eada959bdde927426e2531c9Paul Duffin          this.totalCount += newCount - result[0];
7647dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
7657dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
7667dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7677dd252788645e940eada959bdde927426e2531c9Paul Duffin
7687dd252788645e940eada959bdde927426e2531c9Paul Duffin      // setting my count
7697dd252788645e940eada959bdde927426e2531c9Paul Duffin      result[0] = elemCount;
7707dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (expectedCount == elemCount) {
7717dd252788645e940eada959bdde927426e2531c9Paul Duffin        if (newCount == 0) {
7727dd252788645e940eada959bdde927426e2531c9Paul Duffin          return deleteMe();
7737dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
7747dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.totalCount += newCount - elemCount;
7757dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.elemCount = newCount;
7767dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7777dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
7787dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7797dd252788645e940eada959bdde927426e2531c9Paul Duffin
7807dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> deleteMe() {
7817dd252788645e940eada959bdde927426e2531c9Paul Duffin      int oldElemCount = this.elemCount;
7827dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.elemCount = 0;
7837dd252788645e940eada959bdde927426e2531c9Paul Duffin      successor(pred, succ);
7847dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (left == null) {
7857dd252788645e940eada959bdde927426e2531c9Paul Duffin        return right;
7867dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (right == null) {
7877dd252788645e940eada959bdde927426e2531c9Paul Duffin        return left;
7887dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (left.height >= right.height) {
7897dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> newTop = pred;
7907dd252788645e940eada959bdde927426e2531c9Paul Duffin        // newTop is the maximum node in my left subtree
7917dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.left = left.removeMax(newTop);
7927dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.right = right;
7937dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.distinctElements = distinctElements - 1;
7947dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.totalCount = totalCount - oldElemCount;
7957dd252788645e940eada959bdde927426e2531c9Paul Duffin        return newTop.rebalance();
7963c77433663281544363151bf284b0240dfd22a42Paul Duffin      } else {
7977dd252788645e940eada959bdde927426e2531c9Paul Duffin        AvlNode<E> newTop = succ;
7987dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.right = right.removeMin(newTop);
7997dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.left = left;
8007dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.distinctElements = distinctElements - 1;
8017dd252788645e940eada959bdde927426e2531c9Paul Duffin        newTop.totalCount = totalCount - oldElemCount;
8027dd252788645e940eada959bdde927426e2531c9Paul Duffin        return newTop.rebalance();
8033c77433663281544363151bf284b0240dfd22a42Paul Duffin      }
8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8067dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Removes the minimum node from this subtree to be reused elsewhere
8077dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> removeMin(AvlNode<E> node) {
8087dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (left == null) {
8097dd252788645e940eada959bdde927426e2531c9Paul Duffin        return right;
8107dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
8117dd252788645e940eada959bdde927426e2531c9Paul Duffin        left = left.removeMin(node);
8127dd252788645e940eada959bdde927426e2531c9Paul Duffin        distinctElements--;
8137dd252788645e940eada959bdde927426e2531c9Paul Duffin        totalCount -= node.elemCount;
8147dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
8157dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8167dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8187dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Removes the maximum node from this subtree to be reused elsewhere
8197dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> removeMax(AvlNode<E> node) {
8207dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (right == null) {
8217dd252788645e940eada959bdde927426e2531c9Paul Duffin        return left;
8227dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
8237dd252788645e940eada959bdde927426e2531c9Paul Duffin        right = right.removeMax(node);
8247dd252788645e940eada959bdde927426e2531c9Paul Duffin        distinctElements--;
8257dd252788645e940eada959bdde927426e2531c9Paul Duffin        totalCount -= node.elemCount;
8267dd252788645e940eada959bdde927426e2531c9Paul Duffin        return rebalance();
8277dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8283c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8307dd252788645e940eada959bdde927426e2531c9Paul Duffin    private void recomputeMultiset() {
8317dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.distinctElements = 1 + TreeMultiset.distinctElements(left)
8327dd252788645e940eada959bdde927426e2531c9Paul Duffin          + TreeMultiset.distinctElements(right);
8337dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.totalCount = elemCount + totalCount(left) + totalCount(right);
8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8367dd252788645e940eada959bdde927426e2531c9Paul Duffin    private void recomputeHeight() {
8377dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.height = 1 + Math.max(height(left), height(right));
8387dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8407dd252788645e940eada959bdde927426e2531c9Paul Duffin    private void recompute() {
8417dd252788645e940eada959bdde927426e2531c9Paul Duffin      recomputeMultiset();
8427dd252788645e940eada959bdde927426e2531c9Paul Duffin      recomputeHeight();
8433c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8457dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> rebalance() {
8467dd252788645e940eada959bdde927426e2531c9Paul Duffin      switch (balanceFactor()) {
8477dd252788645e940eada959bdde927426e2531c9Paul Duffin        case -2:
8487dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (right.balanceFactor() > 0) {
8497dd252788645e940eada959bdde927426e2531c9Paul Duffin            right = right.rotateRight();
8507dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
8517dd252788645e940eada959bdde927426e2531c9Paul Duffin          return rotateLeft();
8527dd252788645e940eada959bdde927426e2531c9Paul Duffin        case 2:
8537dd252788645e940eada959bdde927426e2531c9Paul Duffin          if (left.balanceFactor() < 0) {
8547dd252788645e940eada959bdde927426e2531c9Paul Duffin            left = left.rotateLeft();
8557dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
8567dd252788645e940eada959bdde927426e2531c9Paul Duffin          return rotateRight();
8577dd252788645e940eada959bdde927426e2531c9Paul Duffin        default:
8587dd252788645e940eada959bdde927426e2531c9Paul Duffin          recomputeHeight();
8597dd252788645e940eada959bdde927426e2531c9Paul Duffin          return this;
8607dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8637dd252788645e940eada959bdde927426e2531c9Paul Duffin    private int balanceFactor() {
8647dd252788645e940eada959bdde927426e2531c9Paul Duffin      return height(left) - height(right);
8657dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8677dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> rotateLeft() {
8687dd252788645e940eada959bdde927426e2531c9Paul Duffin      checkState(right != null);
8697dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> newTop = right;
8707dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.right = newTop.left;
8717dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.left = this;
8727dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.totalCount = this.totalCount;
8737dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.distinctElements = this.distinctElements;
8747dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.recompute();
8757dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.recomputeHeight();
8767dd252788645e940eada959bdde927426e2531c9Paul Duffin      return newTop;
8773c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
8783c77433663281544363151bf284b0240dfd22a42Paul Duffin
8797dd252788645e940eada959bdde927426e2531c9Paul Duffin    private AvlNode<E> rotateRight() {
8807dd252788645e940eada959bdde927426e2531c9Paul Duffin      checkState(left != null);
8817dd252788645e940eada959bdde927426e2531c9Paul Duffin      AvlNode<E> newTop = left;
8827dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.left = newTop.right;
8837dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.right = this;
8847dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.totalCount = this.totalCount;
8857dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.distinctElements = this.distinctElements;
8867dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.recompute();
8877dd252788645e940eada959bdde927426e2531c9Paul Duffin      newTop.recomputeHeight();
8887dd252788645e940eada959bdde927426e2531c9Paul Duffin      return newTop;
8897dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8907dd252788645e940eada959bdde927426e2531c9Paul Duffin
8917dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static long totalCount(@Nullable AvlNode<?> node) {
8927dd252788645e940eada959bdde927426e2531c9Paul Duffin      return (node == null) ? 0 : node.totalCount;
8937dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8947dd252788645e940eada959bdde927426e2531c9Paul Duffin
8957dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static int height(@Nullable AvlNode<?> node) {
8967dd252788645e940eada959bdde927426e2531c9Paul Duffin      return (node == null) ? 0 : node.height;
8977dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8987dd252788645e940eada959bdde927426e2531c9Paul Duffin
8990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable private AvlNode<E> ceiling(Comparator<? super E> comparator, E e) {
9007dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
9017dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp < 0) {
9023ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        return (left == null) ? this : MoreObjects.firstNonNull(left.ceiling(comparator, e), this);
9037dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp == 0) {
9047dd252788645e940eada959bdde927426e2531c9Paul Duffin        return this;
9057dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
9067dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (right == null) ? null : right.ceiling(comparator, e);
9077dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
9083c77433663281544363151bf284b0240dfd22a42Paul Duffin    }
9093c77433663281544363151bf284b0240dfd22a42Paul Duffin
9100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable private AvlNode<E> floor(Comparator<? super E> comparator, E e) {
9117dd252788645e940eada959bdde927426e2531c9Paul Duffin      int cmp = comparator.compare(e, elem);
9127dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (cmp > 0) {
9133ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin        return (right == null) ? this : MoreObjects.firstNonNull(right.floor(comparator, e), this);
9147dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else if (cmp == 0) {
9157dd252788645e940eada959bdde927426e2531c9Paul Duffin        return this;
9167dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
9177dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (left == null) ? null : left.floor(comparator, e);
9187dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
9197dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
920dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin
9210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
9227dd252788645e940eada959bdde927426e2531c9Paul Duffin    public E getElement() {
9237dd252788645e940eada959bdde927426e2531c9Paul Duffin      return elem;
9247dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9257dd252788645e940eada959bdde927426e2531c9Paul Duffin
9260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
9277dd252788645e940eada959bdde927426e2531c9Paul Duffin    public int getCount() {
9287dd252788645e940eada959bdde927426e2531c9Paul Duffin      return elemCount;
9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
9327dd252788645e940eada959bdde927426e2531c9Paul Duffin    public String toString() {
9337dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Multisets.immutableEntry(getElement(), getCount()).toString();
9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9377dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static <T> void successor(AvlNode<T> a, AvlNode<T> b) {
9387dd252788645e940eada959bdde927426e2531c9Paul Duffin    a.succ = b;
9397dd252788645e940eada959bdde927426e2531c9Paul Duffin    b.pred = a;
9407dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9417dd252788645e940eada959bdde927426e2531c9Paul Duffin
9427dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static <T> void successor(AvlNode<T> a, AvlNode<T> b, AvlNode<T> c) {
9437dd252788645e940eada959bdde927426e2531c9Paul Duffin    successor(a, b);
9447dd252788645e940eada959bdde927426e2531c9Paul Duffin    successor(b, c);
9457dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9467dd252788645e940eada959bdde927426e2531c9Paul Duffin
9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
9487dd252788645e940eada959bdde927426e2531c9Paul Duffin   * TODO(jlevy): Decide whether entrySet() should return entries with an equals() method that
9497dd252788645e940eada959bdde927426e2531c9Paul Duffin   * calls the comparator to compare the two keys. If that change is made,
9507dd252788645e940eada959bdde927426e2531c9Paul Duffin   * AbstractMultiset.equals() can simply check whether two multisets have equal entry sets.
9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
9547dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @serialData the comparator, the number of distinct elements, the first element, its count, the
9557dd252788645e940eada959bdde927426e2531c9Paul Duffin   *             second element, its count, and so on
9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectOutputStream")
9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void writeObject(ObjectOutputStream stream) throws IOException {
9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    stream.defaultWriteObject();
9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    stream.writeObject(elementSet().comparator());
9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Serialization.writeMultiset(this, stream);
9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GwtIncompatible("java.io.ObjectInputStream")
9657dd252788645e940eada959bdde927426e2531c9Paul Duffin  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    stream.defaultReadObject();
9677dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("unchecked")
9687dd252788645e940eada959bdde927426e2531c9Paul Duffin    // reading data stored by writeObject
9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Comparator<? super E> comparator = (Comparator<? super E>) stream.readObject();
9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Serialization.getFieldSetter(AbstractSortedMultiset.class, "comparator").set(this, comparator);
9710888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Serialization.getFieldSetter(TreeMultiset.class, "range").set(
9720888a09821a98ac0680fad765217302858e70fa4Paul Duffin        this,
9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        GeneralRange.all(comparator));
9740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Serialization.getFieldSetter(TreeMultiset.class, "rootReference").set(
9750888a09821a98ac0680fad765217302858e70fa4Paul Duffin        this,
9767dd252788645e940eada959bdde927426e2531c9Paul Duffin        new Reference<AvlNode<E>>());
9777dd252788645e940eada959bdde927426e2531c9Paul Duffin    AvlNode<E> header = new AvlNode<E>(null, 1);
9787dd252788645e940eada959bdde927426e2531c9Paul Duffin    Serialization.getFieldSetter(TreeMultiset.class, "header").set(this, header);
9797dd252788645e940eada959bdde927426e2531c9Paul Duffin    successor(header, header);
9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Serialization.populateMultiset(this, stream);
9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @GwtIncompatible("not needed in emulated source") private static final long serialVersionUID = 1;
9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
985