android/guava/src/com/google/common/collect/Range.java
public Range<C> canonical(DiscreteDomain<C> domain) {
    checkNotNull(domain);
    Cut<C> lower = lowerBound.canonical(domain);
    Cut<C> upper = upperBound.canonical(domain);
    return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper);
  }
public Range<C> canonical(DiscreteDomain<C> domain) {
    checkNotNull(domain);
    Cut<C> lower = lowerBound.canonical(domain);
    Cut<C> upper = upperBound.canonical(domain);
    return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper);
  }
public Range < C > canonical ( DiscreteDomain < C > domain ) { checkNotNull ( domain ) ; Cut < C > lower = lowerBound . canonical ( domain ) ; Cut < C > upper = upperBound . canonical ( domain ) ; return ( lower == lowerBound && upper == upperBound ) ? this : create ( lower , upper ) ; }
Returns the canonical form of this range in the given domain. The canonical form has the
following properties:

<ul>
<li>equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in
other words, {@code ContiguousSet.create(a.canonical(domain), domain).equals(
ContiguousSet.create(a, domain))}
<li>uniqueness: unless {@code a.isEmpty()}, {@code ContiguousSet.create(a,
domain).equals(ContiguousSet.create(b, domain))} implies {@code
a.canonical(domain).equals(b.canonical(domain))}
<li>idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))}
</ul>

<p>Furthermore, this method guarantees that the range returned will be one of the following
canonical forms:

<ul>
<li>[start..end)
<li>[start..+∞)
<li>(-∞..end) (only if type {@code C} is unbounded below)
<li>(-∞..+∞) (only if type {@code C} is unbounded below)
</ul>
Returns the canonical form of this range in the given domain . The canonical form has the following properties :