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).
* Returns an unmodifiable <b>view</b> of the union of two sets. The returned set contains all
   * elements that are contained in either backing set. Iterating over the returned set iterates
   * first over all the elements of {@code set1}, then over each element of {@code set2}, in order,
   * that is not contained in {@code set1}.
   *
   * <p>Results are undefined if {@code set1} and {@code set2} are sets based on different
   * equivalence relations (as {@link HashSet}, {@link TreeSet}, and the {@link Map#keySet} of an
   * {@code IdentityHashMap} all are).
   */
  public static <E> SetView<E> union(final Set<? extends E> set1, final Set<? extends E> set2) {
    checkNotNull(set1, "set1");
    checkNotNull(set2, "set2");
    return new SetView<E>() {
      @Override
      public int size() {
        int size = set1.size();
        for (E e : set2) {
          if (!set1.contains(e)) {
            size++;
          }
        }
        return size;
      }
      @Override
      public boolean isEmpty() {
        return set1.isEmpty() && set2.isEmpty();
      }
      @Override
      public UnmodifiableIterator<E> iterator() {
        return new AbstractIterator<E>() {