This was almost certainly my fault, but as I look at the implementation of Sets.cartesianProduct, I think its `contains` method made the assumption that `ImmutableSet.asList().indexOf` was O(1), which is no longer the case for Android.  It should probably get a specific `contains` implementation that actually is O(sets), not O(sets*setSize).
E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
      return unmodifiableNavigableSet(
          delegate.subSet(fromElement, fromInclusive, toElement, toInclusive));
    }
    @Override
    public NavigableSet<E> headSet(E toElement, boolean inclusive) {
      return unmodifiableNavigableSet(delegate.headSet(toElement, inclusive));
    }
    @Override
    public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
      return unmodifiableNavigableSet(delegate.tailSet(fromElement, inclusive));
    }
    private static final long serialVersionUID = 0;
  }
  /**
   * Returns a synchronized (thread-safe) navigable set backed by the specified navigable set. In
   * order to guarantee serial access, it is critical that <b>all</b> access to the backing
   * navigable set is accomplished through the returned navigable set (or its views).
   *
   * <p>It is imperative that the user manually synchronize on the returned sorted set when
   * iterating over it or any of its {@code descendingSet}, {@code subSet}, {@code headSet}, or
   * {@code tailSet} views.
   *
   * <pre>{@code
   * NavigableSet<E> set = synchronizedNavigableSet(new TreeSet<E>());
   *  ...
   * synchronized (set) {
   *   // Must be in the synchronized block
   *   Iterator<E> it = set.iterator();
   *   while (it.hasNext()) {