/** start and end are BOTH inclusive */
public static long nextLong(Random r, long start, long end) {
assert end >= start;
final BigInteger range = BigInteger.valueOf(end).add(BigInteger.valueOf(1)).subtract(BigInteger.valueOf(start));
if (range.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0) {
return start + r.nextInt(range.intValue());
} else {
// probably not evenly distributed when range is large, but OK for tests
final BigInteger augend = new BigDecimal(range).multiply(new BigDecimal(r.nextDouble())).toBigInteger();
final long result = BigInteger.valueOf(start).add(augend).longValue();
assert result >= start;