1/*
2 * Copyright (C) 2008 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import static com.google.common.collect.BoundType.CLOSED;
20import static com.google.common.collect.BoundType.OPEN;
21import static com.google.common.collect.DiscreteDomains.integers;
22import static com.google.common.testing.SerializableTester.reserializeAndAssert;
23import static java.util.Arrays.asList;
24
25import com.google.common.annotations.GwtCompatible;
26import com.google.common.base.Predicate;
27import com.google.common.collect.testing.Helpers;
28import com.google.common.testing.EqualsTester;
29
30import junit.framework.TestCase;
31
32import java.util.Collections;
33
34/**
35 * Unit test for {@link Range}.
36 *
37 * @author Kevin Bourrillion
38 */
39@GwtCompatible
40public class RangeTest extends TestCase {
41  public void testOpen() {
42    Range<Integer> range = Ranges.open(4, 8);
43    checkContains(range);
44    assertTrue(range.hasLowerBound());
45    assertEquals(4, (int) range.lowerEndpoint());
46    assertEquals(OPEN, range.lowerBoundType());
47    assertTrue(range.hasUpperBound());
48    assertEquals(8, (int) range.upperEndpoint());
49    assertEquals(OPEN, range.upperBoundType());
50    assertFalse(range.isEmpty());
51    assertEquals("(4\u20258)", range.toString());
52    reserializeAndAssert(range);
53  }
54
55  public void testOpen_invalid() {
56    try {
57      Ranges.open(4, 3);
58      fail();
59    } catch (IllegalArgumentException expected) {
60    }
61    try {
62      Ranges.open(3, 3);
63      fail();
64    } catch (IllegalArgumentException expected) {
65    }
66  }
67
68  public void testClosed() {
69    Range<Integer> range = Ranges.closed(5, 7);
70    checkContains(range);
71    assertTrue(range.hasLowerBound());
72    assertEquals(5, (int) range.lowerEndpoint());
73    assertEquals(CLOSED, range.lowerBoundType());
74    assertTrue(range.hasUpperBound());
75    assertEquals(7, (int) range.upperEndpoint());
76    assertEquals(CLOSED, range.upperBoundType());
77    assertFalse(range.isEmpty());
78    assertEquals("[5\u20257]", range.toString());
79    reserializeAndAssert(range);
80  }
81
82  public void testClosed_invalid() {
83    try {
84      Ranges.closed(4, 3);
85      fail();
86    } catch (IllegalArgumentException expected) {
87    }
88  }
89
90  public void testOpenClosed() {
91    Range<Integer> range = Ranges.openClosed(4, 7);
92    checkContains(range);
93    assertTrue(range.hasLowerBound());
94    assertEquals(4, (int) range.lowerEndpoint());
95    assertEquals(OPEN, range.lowerBoundType());
96    assertTrue(range.hasUpperBound());
97    assertEquals(7, (int) range.upperEndpoint());
98    assertEquals(CLOSED, range.upperBoundType());
99    assertFalse(range.isEmpty());
100    assertEquals("(4\u20257]", range.toString());
101    reserializeAndAssert(range);
102  }
103
104  public void testClosedOpen() {
105    Range<Integer> range = Ranges.closedOpen(5, 8);
106    checkContains(range);
107    assertTrue(range.hasLowerBound());
108    assertEquals(5, (int) range.lowerEndpoint());
109    assertEquals(CLOSED, range.lowerBoundType());
110    assertTrue(range.hasUpperBound());
111    assertEquals(8, (int) range.upperEndpoint());
112    assertEquals(OPEN, range.upperBoundType());
113    assertFalse(range.isEmpty());
114    assertEquals("[5\u20258)", range.toString());
115    reserializeAndAssert(range);
116  }
117
118  public void testIsConnected() {
119    assertTrue(Ranges.closed(3, 5).isConnected(Ranges.open(5, 6)));
120    assertTrue(Ranges.closed(3, 5).isConnected(Ranges.openClosed(5, 5)));
121    assertTrue(Ranges.open(3, 5).isConnected(Ranges.closed(5, 6)));
122    assertTrue(Ranges.closed(3, 7).isConnected(Ranges.open(6, 8)));
123    assertTrue(Ranges.open(3, 7).isConnected(Ranges.closed(5, 6)));
124    assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closed(7, 8)));
125    assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closedOpen(7, 7)));
126  }
127
128  private static void checkContains(Range<Integer> range) {
129    assertFalse(range.contains(4));
130    assertTrue(range.contains(5));
131    assertTrue(range.contains(7));
132    assertFalse(range.contains(8));
133  }
134
135  public void testSingleton() {
136    Range<Integer> range = Ranges.closed(4, 4);
137    assertFalse(range.contains(3));
138    assertTrue(range.contains(4));
139    assertFalse(range.contains(5));
140    assertTrue(range.hasLowerBound());
141    assertEquals(4, (int) range.lowerEndpoint());
142    assertEquals(CLOSED, range.lowerBoundType());
143    assertTrue(range.hasUpperBound());
144    assertEquals(4, (int) range.upperEndpoint());
145    assertEquals(CLOSED, range.upperBoundType());
146    assertFalse(range.isEmpty());
147    assertEquals("[4\u20254]", range.toString());
148    reserializeAndAssert(range);
149  }
150
151  public void testEmpty1() {
152    Range<Integer> range = Ranges.closedOpen(4, 4);
153    assertFalse(range.contains(3));
154    assertFalse(range.contains(4));
155    assertFalse(range.contains(5));
156    assertTrue(range.hasLowerBound());
157    assertEquals(4, (int) range.lowerEndpoint());
158    assertEquals(CLOSED, range.lowerBoundType());
159    assertTrue(range.hasUpperBound());
160    assertEquals(4, (int) range.upperEndpoint());
161    assertEquals(OPEN, range.upperBoundType());
162    assertTrue(range.isEmpty());
163    assertEquals("[4\u20254)", range.toString());
164    reserializeAndAssert(range);
165  }
166
167  public void testEmpty2() {
168    Range<Integer> range = Ranges.openClosed(4, 4);
169    assertFalse(range.contains(3));
170    assertFalse(range.contains(4));
171    assertFalse(range.contains(5));
172    assertTrue(range.hasLowerBound());
173    assertEquals(4, (int) range.lowerEndpoint());
174    assertEquals(OPEN, range.lowerBoundType());
175    assertTrue(range.hasUpperBound());
176    assertEquals(4, (int) range.upperEndpoint());
177    assertEquals(CLOSED, range.upperBoundType());
178    assertTrue(range.isEmpty());
179    assertEquals("(4\u20254]", range.toString());
180    reserializeAndAssert(range);
181  }
182
183  public void testLessThan() {
184    Range<Integer> range = Ranges.lessThan(5);
185    assertTrue(range.contains(Integer.MIN_VALUE));
186    assertTrue(range.contains(4));
187    assertFalse(range.contains(5));
188    assertUnboundedBelow(range);
189    assertTrue(range.hasUpperBound());
190    assertEquals(5, (int) range.upperEndpoint());
191    assertEquals(OPEN, range.upperBoundType());
192    assertFalse(range.isEmpty());
193    assertEquals("(-\u221e\u20255)", range.toString());
194    reserializeAndAssert(range);
195  }
196
197  public void testGreaterThan() {
198    Range<Integer> range = Ranges.greaterThan(5);
199    assertFalse(range.contains(5));
200    assertTrue(range.contains(6));
201    assertTrue(range.contains(Integer.MAX_VALUE));
202    assertTrue(range.hasLowerBound());
203    assertEquals(5, (int) range.lowerEndpoint());
204    assertEquals(OPEN, range.lowerBoundType());
205    assertUnboundedAbove(range);
206    assertFalse(range.isEmpty());
207    assertEquals("(5\u2025+\u221e)", range.toString());
208    reserializeAndAssert(range);
209  }
210
211  public void testAtLeast() {
212    Range<Integer> range = Ranges.atLeast(6);
213    assertFalse(range.contains(5));
214    assertTrue(range.contains(6));
215    assertTrue(range.contains(Integer.MAX_VALUE));
216    assertTrue(range.hasLowerBound());
217    assertEquals(6, (int) range.lowerEndpoint());
218    assertEquals(CLOSED, range.lowerBoundType());
219    assertUnboundedAbove(range);
220    assertFalse(range.isEmpty());
221    assertEquals("[6\u2025+\u221e)", range.toString());
222    reserializeAndAssert(range);
223  }
224
225  public void testAtMost() {
226    Range<Integer> range = Ranges.atMost(4);
227    assertTrue(range.contains(Integer.MIN_VALUE));
228    assertTrue(range.contains(4));
229    assertFalse(range.contains(5));
230    assertUnboundedBelow(range);
231    assertTrue(range.hasUpperBound());
232    assertEquals(4, (int) range.upperEndpoint());
233    assertEquals(CLOSED, range.upperBoundType());
234    assertFalse(range.isEmpty());
235    assertEquals("(-\u221e\u20254]", range.toString());
236    reserializeAndAssert(range);
237  }
238
239  public void testAll() {
240    Range<Integer> range = Ranges.all();
241    assertTrue(range.contains(Integer.MIN_VALUE));
242    assertTrue(range.contains(Integer.MAX_VALUE));
243    assertUnboundedBelow(range);
244    assertUnboundedAbove(range);
245    assertFalse(range.isEmpty());
246    assertEquals("(-\u221e\u2025+\u221e)", range.toString());
247    reserializeAndAssert(range);
248  }
249
250  private static void assertUnboundedBelow(Range<Integer> range) {
251    assertFalse(range.hasLowerBound());
252    try {
253      range.lowerEndpoint();
254      fail();
255    } catch (IllegalStateException expected) {
256    }
257    try {
258      range.lowerBoundType();
259      fail();
260    } catch (IllegalStateException expected) {
261    }
262  }
263
264  private static void assertUnboundedAbove(Range<Integer> range) {
265    assertFalse(range.hasUpperBound());
266    try {
267      range.upperEndpoint();
268      fail();
269    } catch (IllegalStateException expected) {
270    }
271    try {
272      range.upperBoundType();
273      fail();
274    } catch (IllegalStateException expected) {
275    }
276  }
277
278  public void testOrderingCuts() {
279    Cut<Integer> a = Ranges.lessThan(0).lowerBound;
280    Cut<Integer> b = Ranges.atLeast(0).lowerBound;
281    Cut<Integer> c = Ranges.greaterThan(0).lowerBound;
282    Cut<Integer> d = Ranges.atLeast(1).lowerBound;
283    Cut<Integer> e = Ranges.greaterThan(1).lowerBound;
284    Cut<Integer> f = Ranges.greaterThan(1).upperBound;
285
286    Helpers.testCompareToAndEquals(ImmutableList.of(a, b, c, d, e, f));
287  }
288
289  public void testContainsAll() {
290    Range<Integer> range = Ranges.closed(3, 5);
291    assertTrue(range.containsAll(asList(3, 3, 4, 5)));
292    assertFalse(range.containsAll(asList(3, 3, 4, 5, 6)));
293
294    // We happen to know that natural-order sorted sets use a different code
295    // path, so we test that separately
296    assertTrue(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5)));
297    assertTrue(range.containsAll(ImmutableSortedSet.of(3)));
298    assertTrue(range.containsAll(ImmutableSortedSet.<Integer>of()));
299    assertFalse(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5, 6)));
300
301    assertTrue(Ranges.openClosed(3, 3).containsAll(
302        Collections.<Integer>emptySet()));
303  }
304
305  public void testEncloses_open() {
306    Range<Integer> range = Ranges.open(2, 5);
307    assertTrue(range.encloses(range));
308    assertTrue(range.encloses(Ranges.open(2, 4)));
309    assertTrue(range.encloses(Ranges.open(3, 5)));
310    assertTrue(range.encloses(Ranges.closed(3, 4)));
311
312    assertFalse(range.encloses(Ranges.openClosed(2, 5)));
313    assertFalse(range.encloses(Ranges.closedOpen(2, 5)));
314    assertFalse(range.encloses(Ranges.closed(1, 4)));
315    assertFalse(range.encloses(Ranges.closed(3, 6)));
316    assertFalse(range.encloses(Ranges.greaterThan(3)));
317    assertFalse(range.encloses(Ranges.lessThan(3)));
318    assertFalse(range.encloses(Ranges.atLeast(3)));
319    assertFalse(range.encloses(Ranges.atMost(3)));
320    assertFalse(range.encloses(Ranges.<Integer>all()));
321  }
322
323  public void testEncloses_closed() {
324    Range<Integer> range = Ranges.closed(2, 5);
325    assertTrue(range.encloses(range));
326    assertTrue(range.encloses(Ranges.open(2, 5)));
327    assertTrue(range.encloses(Ranges.openClosed(2, 5)));
328    assertTrue(range.encloses(Ranges.closedOpen(2, 5)));
329    assertTrue(range.encloses(Ranges.closed(3, 5)));
330    assertTrue(range.encloses(Ranges.closed(2, 4)));
331
332    assertFalse(range.encloses(Ranges.open(1, 6)));
333    assertFalse(range.encloses(Ranges.greaterThan(3)));
334    assertFalse(range.encloses(Ranges.lessThan(3)));
335    assertFalse(range.encloses(Ranges.atLeast(3)));
336    assertFalse(range.encloses(Ranges.atMost(3)));
337    assertFalse(range.encloses(Ranges.<Integer>all()));
338  }
339
340  public void testIntersection_empty() {
341    Range<Integer> range = Ranges.closedOpen(3, 3);
342    assertEquals(range, range.intersection(range));
343
344    try {
345      range.intersection(Ranges.open(3, 5));
346      fail();
347    } catch (IllegalArgumentException expected) {
348    }
349    try {
350      range.intersection(Ranges.closed(0, 2));
351      fail();
352    } catch (IllegalArgumentException expected) {
353    }
354  }
355
356  public void testIntersection_deFactoEmpty() {
357    Range<Integer> range = Ranges.open(3, 4);
358    assertEquals(range, range.intersection(range));
359
360    assertEquals(Ranges.openClosed(3, 3),
361        range.intersection(Ranges.atMost(3)));
362    assertEquals(Ranges.closedOpen(4, 4),
363        range.intersection(Ranges.atLeast(4)));
364
365    try {
366      range.intersection(Ranges.lessThan(3));
367      fail();
368    } catch (IllegalArgumentException expected) {
369    }
370    try {
371      range.intersection(Ranges.greaterThan(4));
372      fail();
373    } catch (IllegalArgumentException expected) {
374    }
375
376    range = Ranges.closed(3, 4);
377    assertEquals(Ranges.openClosed(4, 4),
378        range.intersection(Ranges.greaterThan(4)));
379  }
380
381  public void testIntersection_singleton() {
382    Range<Integer> range = Ranges.closed(3, 3);
383    assertEquals(range, range.intersection(range));
384
385    assertEquals(range, range.intersection(Ranges.atMost(4)));
386    assertEquals(range, range.intersection(Ranges.atMost(3)));
387    assertEquals(range, range.intersection(Ranges.atLeast(3)));
388    assertEquals(range, range.intersection(Ranges.atLeast(2)));
389
390    assertEquals(Ranges.closedOpen(3, 3),
391        range.intersection(Ranges.lessThan(3)));
392    assertEquals(Ranges.openClosed(3, 3),
393        range.intersection(Ranges.greaterThan(3)));
394
395    try {
396      range.intersection(Ranges.atLeast(4));
397      fail();
398    } catch (IllegalArgumentException expected) {
399    }
400    try {
401      range.intersection(Ranges.atMost(2));
402      fail();
403    } catch (IllegalArgumentException expected) {
404    }
405  }
406
407  public void testIntersection_general() {
408    Range<Integer> range = Ranges.closed(4, 8);
409
410    // separate below
411    try {
412      range.intersection(Ranges.closed(0, 2));
413      fail();
414    } catch (IllegalArgumentException expected) {
415    }
416
417    // adjacent below
418    assertEquals(Ranges.closedOpen(4, 4),
419        range.intersection(Ranges.closedOpen(2, 4)));
420
421    // overlap below
422    assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(2, 6)));
423
424    // enclosed with same start
425    assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(4, 6)));
426
427    // enclosed, interior
428    assertEquals(Ranges.closed(5, 7), range.intersection(Ranges.closed(5, 7)));
429
430    // enclosed with same end
431    assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 8)));
432
433    // equal
434    assertEquals(range, range.intersection(range));
435
436    // enclosing with same start
437    assertEquals(range, range.intersection(Ranges.closed(4, 10)));
438
439    // enclosing with same end
440    assertEquals(range, range.intersection(Ranges.closed(2, 8)));
441
442    // enclosing, exterior
443    assertEquals(range, range.intersection(Ranges.closed(2, 10)));
444
445    // overlap above
446    assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 10)));
447
448    // adjacent above
449    assertEquals(Ranges.openClosed(8, 8),
450        range.intersection(Ranges.openClosed(8, 10)));
451
452    // separate above
453    try {
454      range.intersection(Ranges.closed(10, 12));
455      fail();
456    } catch (IllegalArgumentException expected) {
457    }
458  }
459
460  public void testSpan_general() {
461    Range<Integer> range = Ranges.closed(4, 8);
462
463    // separate below
464    assertEquals(Ranges.closed(0, 8), range.span(Ranges.closed(0, 2)));
465    assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(2)));
466
467    // adjacent below
468    assertEquals(Ranges.closed(2, 8), range.span(Ranges.closedOpen(2, 4)));
469    assertEquals(Ranges.atMost(8), range.span(Ranges.lessThan(4)));
470
471    // overlap below
472    assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 6)));
473    assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(6)));
474
475    // enclosed with same start
476    assertEquals(range, range.span(Ranges.closed(4, 6)));
477
478    // enclosed, interior
479    assertEquals(range, range.span(Ranges.closed(5, 7)));
480
481    // enclosed with same end
482    assertEquals(range, range.span(Ranges.closed(6, 8)));
483
484    // equal
485    assertEquals(range, range.span(range));
486
487    // enclosing with same start
488    assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(4, 10)));
489    assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(4)));
490
491    // enclosing with same end
492    assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 8)));
493    assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(8)));
494
495    // enclosing, exterior
496    assertEquals(Ranges.closed(2, 10), range.span(Ranges.closed(2, 10)));
497    assertEquals(Ranges.<Integer>all(), range.span(Ranges.<Integer>all()));
498
499    // overlap above
500    assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(6, 10)));
501    assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(6)));
502
503    // adjacent above
504    assertEquals(Ranges.closed(4, 10), range.span(Ranges.openClosed(8, 10)));
505    assertEquals(Ranges.atLeast(4), range.span(Ranges.greaterThan(8)));
506
507    // separate above
508    assertEquals(Ranges.closed(4, 12), range.span(Ranges.closed(10, 12)));
509    assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(10)));
510  }
511
512  public void testApply() {
513    Predicate<Integer> predicate = Ranges.closed(2, 3);
514    assertFalse(predicate.apply(1));
515    assertTrue(predicate.apply(2));
516    assertTrue(predicate.apply(3));
517    assertFalse(predicate.apply(4));
518  }
519
520  public void testEquals() {
521    new EqualsTester()
522        .addEqualityGroup(Ranges.open(1, 5),
523            Ranges.range(1, OPEN, 5, OPEN))
524        .addEqualityGroup(Ranges.greaterThan(2), Ranges.greaterThan(2))
525        .addEqualityGroup(Ranges.all(), Ranges.all())
526        .addEqualityGroup("Phil")
527        .testEquals();
528  }
529
530  public void testLegacyComparable() {
531    Range<LegacyComparable> range
532        = Ranges.closed(LegacyComparable.X, LegacyComparable.Y);
533  }
534
535  private static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN =
536      new DiscreteDomain<Integer>() {
537        @Override public Integer next(Integer value) {
538          return DiscreteDomains.integers().next(value);
539        }
540
541        @Override public Integer previous(Integer value) {
542          return DiscreteDomains.integers().previous(value);
543        }
544
545        @Override public long distance(Integer start, Integer end) {
546          return DiscreteDomains.integers().distance(start, end);
547        }
548      };
549
550  public void testAsSet_noMin() {
551    Range<Integer> range = Ranges.lessThan(0);
552    try {
553      range.asSet(UNBOUNDED_DOMAIN);
554      fail();
555    } catch (IllegalArgumentException expected) {}
556  }
557
558  public void testAsSet_noMax() {
559    Range<Integer> range = Ranges.greaterThan(0);
560    try {
561      range.asSet(UNBOUNDED_DOMAIN);
562      fail();
563    } catch (IllegalArgumentException expected) {}
564  }
565
566  public void testAsSet_empty() {
567    assertEquals(ImmutableSet.of(), Ranges.closedOpen(1, 1).asSet(integers()));
568    assertEquals(ImmutableSet.of(), Ranges.openClosed(5, 5).asSet(integers()));
569    assertEquals(ImmutableSet.of(), Ranges.lessThan(Integer.MIN_VALUE).asSet(integers()));
570    assertEquals(ImmutableSet.of(), Ranges.greaterThan(Integer.MAX_VALUE).asSet(integers()));
571  }
572
573  public void testCanonical() {
574    assertEquals(Ranges.closedOpen(1, 5),
575        Ranges.closed(1, 4).canonical(integers()));
576    assertEquals(Ranges.closedOpen(1, 5),
577        Ranges.open(0, 5).canonical(integers()));
578    assertEquals(Ranges.closedOpen(1, 5),
579        Ranges.closedOpen(1, 5).canonical(integers()));
580    assertEquals(Ranges.closedOpen(1, 5),
581        Ranges.openClosed(0, 4).canonical(integers()));
582
583    assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
584        Ranges.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
585
586    assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
587        Ranges.lessThan(0).canonical(integers()));
588    assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 1),
589        Ranges.atMost(0).canonical(integers()));
590    assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(integers()));
591    assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(integers()));
592
593    assertEquals(Ranges.atLeast(Integer.MIN_VALUE), Ranges.<Integer>all().canonical(integers()));
594  }
595
596  public void testCanonical_unboundedDomain() {
597    assertEquals(Ranges.lessThan(0), Ranges.lessThan(0).canonical(UNBOUNDED_DOMAIN));
598    assertEquals(Ranges.lessThan(1), Ranges.atMost(0).canonical(UNBOUNDED_DOMAIN));
599    assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(UNBOUNDED_DOMAIN));
600    assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
601
602    assertEquals(Ranges.all(), Ranges.<Integer>all().canonical(UNBOUNDED_DOMAIN));
603  }
604}
605