Accidentally using different types for the lower and upper endpoint produces a `ClassCastException` when validating that the lower endpoint isn't above the upper endpoint. This is a little surprising.

For example, the following:

```java
Range<? extends Number> range = Range.closedOpen(0, 1.0);
```

results in

```
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
        at java.lang.Integer.compareTo(Integer.java:52)
        at com.google.common.collect.Range.compareOrThrow(Range.java:690)
        at com.google.common.collect.Cut.compareTo(Cut.java:77)
        at com.google.common.collect.Range.<init>(Range.java:349)
        at com.google.common.collect.Range.create(Range.java:155)
        at com.google.common.collect.Range.closedOpen(Range.java:189)
```

(In the actual code I'm looking at, the `range` variable is a function parameter that must accept numeric ranges of different types, so it's less weird than it looks here.)

Now, the range produced here _is_ completely invalid, and there's no way that the compiler can check this (because we can't express that the two bounds parameters must be the same concrete type, or at worst be mutually comparable).

However, it would be nice if `Range.compareOrThrow()` caught `ClassCastException` and returned a clearer message, or just chained the CCE onto the "Invalid range" `IllegalArgumentException` it can already throw.

I note that `Range.compareOrThrow()` has a "may throw CCE" comment, but the only place that this exception is mentioned otherwise is in the Javadoc for `Range.encloseAll()` and a comment in `Range.contains()`, both of which are talking about their function arguments.
*       <b>This may change in the future.</b>
 * </ul>
 *
 * <h3>Other notes</h3>
 *
 * <ul>
 *   <li>Instances of this type are obtained using the static factory methods in this class.
 *   <li>Ranges are <i>convex</i>: whenever two values are contained, all values in between them
 *       must also be contained. More formally, for any {@code c1 <= c2 <= c3} of type {@code C},
 *       {@code r.contains(c1) && r.contains(c3)} implies {@code r.contains(c2)}). This means that a
 *       {@code Range<Integer>} can never be used to represent, say, "all <i>prime</i> numbers from
 *       1 to 100."
 *   <li>When evaluated as a {@link Predicate}, a range yields the same result as invoking {@link
 *       #contains}.
 *   <li>Terminology note: a range {@code a} is said to be the <i>maximal</i> range having property
 *       <i>P</i> if, for all ranges {@code b} also having property <i>P</i>, {@code a.encloses(b)}.
 *       Likewise, {@code a} is <i>minimal</i> when {@code b.encloses(a)} for all {@code b} having
 *       property <i>P</i>. See, for example, the definition of {@link #intersection intersection}.
 * </ul>
 *
 * <h3>Further reading</h3>
 *
 * <p>See the Guava User Guide article on <a
 * href="https://github.com/google/guava/wiki/RangesExplained">{@code Range}</a>.
 *
 * @author Kevin Bourrillion
 * @author Gregory Kick
 * @since 10.0
 */
@GwtCompatible