diff --git a/commons-rng-client-api/pom.xml b/commons-rng-client-api/pom.xml
index 86353b0..8caa901 100644
--- a/commons-rng-client-api/pom.xml
+++ b/commons-rng-client-api/pom.xml
@@ -42,4 +42,31 @@
     <rng.jira.component>client-api</rng.jira.component>
   </properties>
 
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.github.siom79.japicmp</groupId>
+        <artifactId>japicmp-maven-plugin</artifactId>
+        <configuration>
+          <parameter>
+            <!-- Adding Java 8 default methods should not break binary compatibility. -->
+            <overrideCompatibilityChangeParameters>
+              <overrideCompatibilityChangeParameter>
+                <compatibilityChange>METHOD_NEW_DEFAULT</compatibilityChange>
+                <binaryCompatible>true</binaryCompatible>
+                <sourceCompatible>true</sourceCompatible>
+                <semanticVersionLevel>PATCH</semanticVersionLevel>
+              </overrideCompatibilityChangeParameter>
+              <overrideCompatibilityChangeParameter>
+                <compatibilityChange>METHOD_ABSTRACT_NOW_DEFAULT</compatibilityChange>
+                <binaryCompatible>true</binaryCompatible>
+                <sourceCompatible>true</sourceCompatible>
+                <semanticVersionLevel>PATCH</semanticVersionLevel>
+              </overrideCompatibilityChangeParameter>
+            </overrideCompatibilityChangeParameters>
+          </parameter>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProvider.java b/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProvider.java
index 07d3108..1c48564 100644
--- a/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProvider.java
+++ b/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProvider.java
@@ -16,6 +16,10 @@
  */
 package org.apache.commons.rng;
 
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+
 /**
  * Applies to generators of random number sequences that follow a uniform
  * distribution.
@@ -25,24 +29,23 @@
 public interface UniformRandomProvider {
     /**
      * Generates {@code byte} values and places them into a user-supplied array.
-     * <p>
-     * The number of random bytes produced is equal to the length of the
+     *
+     * <p>The number of random bytes produced is equal to the length of the
      * the byte array.
-     * </p>
      *
      * @param bytes Byte array in which to put the random bytes.
      * Cannot be {@code null}.
      */
-    void nextBytes(byte[] bytes);
+    default void nextBytes(byte[] bytes) {
+        UniformRandomProviderSupport.nextBytes(this, bytes, 0, bytes.length);
+    }
 
     /**
      * Generates {@code byte} values and places them into a user-supplied array.
      *
-     * <p>
-     * The array is filled with bytes extracted from random integers.
+     * <p>The array is filled with bytes extracted from random integers.
      * This implies that the number of random bytes generated may be larger than
      * the length of the byte array.
-     * </p>
      *
      * @param bytes Array in which to put the generated bytes.
      * Cannot be {@code null}.
@@ -53,16 +56,19 @@
      * @throws IndexOutOfBoundsException if {@code len < 0} or
      * {@code len > bytes.length - start}.
      */
-    void nextBytes(byte[] bytes,
-                   int start,
-                   int len);
+    default void nextBytes(byte[] bytes, int start, int len) {
+        UniformRandomProviderSupport.validateFromIndexSize(start, len, bytes.length);
+        UniformRandomProviderSupport.nextBytes(this, bytes, start, len);
+    }
 
     /**
      * Generates an {@code int} value.
      *
      * @return the next random value.
      */
-    int nextInt();
+    default int nextInt() {
+        return (int) (nextLong() >>> 32);
+    }
 
     /**
      * Generates an {@code int} value between 0 (inclusive) and the
@@ -71,9 +77,29 @@
      * @param n Bound on the random number to be returned.  Must be positive.
      * @return a random {@code int} value between 0 (inclusive) and {@code n}
      * (exclusive).
-     * @throws IllegalArgumentException if {@code n} is negative.
+     * @throws IllegalArgumentException if {@code n} is not above zero.
      */
-    int nextInt(int n);
+    default int nextInt(int n) {
+        UniformRandomProviderSupport.validateUpperBound(n);
+        return UniformRandomProviderSupport.nextInt(this, n);
+    }
+
+    /**
+     * Generates an {@code int} value between the specified {@code origin} (inclusive) and
+     * the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code int} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     * @since 1.5
+     */
+    default int nextInt(int origin, int bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return UniformRandomProviderSupport.nextInt(this, origin, bound);
+    }
 
     /**
      * Generates a {@code long} value.
@@ -89,28 +115,308 @@
      * @param n Bound on the random number to be returned.  Must be positive.
      * @return a random {@code long} value between 0 (inclusive) and {@code n}
      * (exclusive).
-     * @throws IllegalArgumentException if {@code n} is negative.
+     * @throws IllegalArgumentException if {@code n} is not greater than 0.
      */
-    long nextLong(long n);
+    default long nextLong(long n) {
+        UniformRandomProviderSupport.validateUpperBound(n);
+        return UniformRandomProviderSupport.nextLong(this, n);
+    }
+
+    /**
+     * Generates a {@code long} value between the specified {@code origin} (inclusive) and
+     * the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code long} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     * @since 1.5
+     */
+    default long nextLong(long origin, long bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return UniformRandomProviderSupport.nextLong(this, origin, bound);
+    }
 
     /**
      * Generates a {@code boolean} value.
      *
      * @return the next random value.
      */
-    boolean nextBoolean();
+    default boolean nextBoolean() {
+        return nextInt() < 0;
+    }
 
     /**
-     * Generates a {@code float} value between 0 and 1.
+     * Generates a {@code float} value between 0 (inclusive) and 1 (exclusive).
      *
-     * @return the next random value between 0 and 1.
+     * @return the next random value between 0 (inclusive) and 1 (exclusive).
      */
-    float nextFloat();
+    default float nextFloat() {
+        return (nextInt() >>> 8) * 0x1.0p-24f;
+    }
 
     /**
-     * Generates a {@code double} value between 0 and 1.
+     * Generates a {@code float} value between 0 (inclusive) and the
+     * specified {@code bound} (exclusive).
      *
-     * @return the next random value between 0 and 1.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code float} value between 0 (inclusive) and {@code bound}
+     * (exclusive).
+     * @throws IllegalArgumentException if {@code bound} is not both finite and greater than 0.
+     * @since 1.5
      */
-    double nextDouble();
+    default float nextFloat(float bound) {
+        UniformRandomProviderSupport.validateUpperBound(bound);
+        return UniformRandomProviderSupport.nextFloat(this, bound);
+    }
+
+    /**
+     * Generates a {@code float} value between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code float} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound}
+     * is not finite, or {@code origin} is greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default float nextFloat(float origin, float bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return UniformRandomProviderSupport.nextFloat(this, origin, bound);
+    }
+
+    /**
+     * Generates a {@code double} value between 0 (inclusive) and 1 (exclusive).
+     *
+     * @return the next random value between 0 (inclusive) and 1 (exclusive).
+     */
+    default double nextDouble() {
+        return (nextLong() >>> 11) * 0x1.0p-53;
+    }
+
+    /**
+     * Generates a {@code double} value between 0 (inclusive) and the
+     * specified {@code bound} (exclusive).
+     *
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code double} value between 0 (inclusive) and {@code bound}
+     * (exclusive).
+     * @throws IllegalArgumentException if {@code bound} is not both finite and greater than 0.
+     * @since 1.5
+     */
+    default double nextDouble(double bound) {
+        UniformRandomProviderSupport.validateUpperBound(bound);
+        return UniformRandomProviderSupport.nextDouble(this, bound);
+    }
+
+    /**
+     * Generates a {@code double} value between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a random {@code double} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound}
+     * is not finite, or {@code origin} is greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default double nextDouble(double origin, double bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return UniformRandomProviderSupport.nextDouble(this, origin, bound);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code int} values.
+     *
+     * @return a stream of random {@code int} values.
+     * @since 1.5
+     */
+    default IntStream ints() {
+        return IntStream.generate(this::nextInt).sequential();
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code int} values between the specified
+     * {@code origin} (inclusive) and the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     * @since 1.5
+     */
+    default IntStream ints(int origin, int bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return IntStream.generate(() -> nextInt(origin, bound)).sequential();
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code int}
+     * values.
+     *
+     * @param streamSize Number of values to generate.
+     * @return a stream of random {@code int} values. the stream is limited to the given
+     * {@code streamSize}.
+     * @throws IllegalArgumentException if {@code streamSize} is negative.
+     * @since 1.5
+     */
+    default IntStream ints(long streamSize) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        return ints().limit(streamSize);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code int}
+     * values between the specified {@code origin} (inclusive) and the specified
+     * {@code bound} (exclusive).
+     *
+     * @param streamSize Number of values to generate.
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive); the stream is limited to the given
+     * {@code streamSize}.
+     * @throws IllegalArgumentException if {@code streamSize} is negative, or if
+     * {@code origin} is greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default IntStream ints(long streamSize, int origin, int bound) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return ints(origin, bound).limit(streamSize);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code long} values.
+     *
+     * @return a stream of random {@code long} values.
+     * @since 1.5
+     */
+    default LongStream longs() {
+        return LongStream.generate(this::nextLong).sequential();
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code long} values between the
+     * specified {@code origin} (inclusive) and the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     * @since 1.5
+     */
+    default LongStream longs(long origin, long bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return LongStream.generate(() -> nextLong(origin, bound)).sequential();
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code long}
+     * values.
+     *
+     * @param streamSize Number of values to generate.
+     * @return a stream of random {@code long} values. the stream is limited to the given
+     * {@code streamSize}.
+     * @throws IllegalArgumentException if {@code streamSize} is negative.
+     * @since 1.5
+     */
+    default LongStream longs(long streamSize) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        return longs().limit(streamSize);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code long}
+     * values between the specified {@code origin} (inclusive) and the specified
+     * {@code bound} (exclusive).
+     *
+     * @param streamSize Number of values to generate.
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive); the stream is limited to the given
+     * {@code streamSize}.
+     * @throws IllegalArgumentException if {@code streamSize} is negative, or if
+     * {@code origin} is greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default LongStream longs(long streamSize, long origin, long bound) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return longs(origin, bound).limit(streamSize);
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code double} values between 0
+     * (inclusive) and 1 (exclusive).
+     *
+     * @return a stream of random values between 0 (inclusive) and 1 (exclusive).
+     * @since 1.5
+     */
+    default DoubleStream doubles() {
+        return DoubleStream.generate(this::nextDouble).sequential();
+    }
+
+    /**
+     * Returns an effectively unlimited stream of {@code double} values between the
+     * specified {@code origin} (inclusive) and the specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound}
+     * is not finite, or {@code origin} is greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default DoubleStream doubles(double origin, double bound) {
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return DoubleStream.generate(() -> nextDouble(origin, bound)).sequential();
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code double}
+     * values between 0 (inclusive) and 1 (exclusive).
+     *
+     * @param streamSize Number of values to generate.
+     * @return a stream of random values between 0 (inclusive) and 1 (exclusive).
+     * @throws IllegalArgumentException if {@code streamSize} is negative.
+     * @since 1.5
+     */
+    default DoubleStream doubles(long streamSize) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        return doubles().limit(streamSize);
+    }
+
+    /**
+     * Returns a stream producing the given {@code streamSize} number of {@code double}
+     * values between the specified {@code origin} (inclusive) and the specified
+     * {@code bound} (exclusive).
+     *
+     * @param streamSize Number of values to generate.
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @return a stream of random values between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive); the stream is limited to the given
+     * {@code streamSize}.
+     * @throws IllegalArgumentException if {@code streamSize} is negative, or if
+     * {@code origin} is not finite, or {@code bound} is not finite, or {@code origin} is
+     * greater than or equal to {@code bound}.
+     * @since 1.5
+     */
+    default DoubleStream doubles(long streamSize, double origin, double bound) {
+        UniformRandomProviderSupport.validateStreamSize(streamSize);
+        UniformRandomProviderSupport.validateRange(origin, bound);
+        return doubles(origin, bound).limit(streamSize);
+    }
 }
diff --git a/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProviderSupport.java b/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProviderSupport.java
new file mode 100644
index 0000000..b798103
--- /dev/null
+++ b/commons-rng-client-api/src/main/java/org/apache/commons/rng/UniformRandomProviderSupport.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng;
+
+/**
+ * Support for {@link UniformRandomProvider} default methods.
+ *
+ * @since 1.5
+ */
+final class UniformRandomProviderSupport {
+    /** Message for an invalid stream size. */
+    private static final String INVALID_STREAM_SIZE = "Invalid stream size: ";
+    /** Message for an invalid upper bound (must be positive, finite and above zero). */
+    private static final String INVALID_UPPER_BOUND = "Upper bound must be above zero: ";
+    /** Message format for an invalid range for lower inclusive and upper exclusive. */
+    private static final String INVALID_RANGE = "Invalid range: [%s, %s)";
+    /** 2^32. */
+    private static final long POW_32 = 1L << 32;
+
+    /** No instances. */
+    private UniformRandomProviderSupport() {}
+
+    /**
+     * Validate the stream size.
+     *
+     * @param size Stream size.
+     * @throws IllegalArgumentException if {@code size} is negative.
+     */
+    static void validateStreamSize(long size) {
+        if (size < 0) {
+            throw new IllegalArgumentException(INVALID_STREAM_SIZE + size);
+        }
+    }
+
+    /**
+     * Validate the upper bound.
+     *
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code bound} is equal to or less than zero.
+     */
+    static void validateUpperBound(int bound) {
+        if (bound <= 0) {
+            throw new IllegalArgumentException(INVALID_UPPER_BOUND + bound);
+        }
+    }
+
+    /**
+     * Validate the upper bound.
+     *
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code bound} is equal to or less than zero.
+     */
+    static void validateUpperBound(long bound) {
+        if (bound <= 0) {
+            throw new IllegalArgumentException(INVALID_UPPER_BOUND + bound);
+        }
+    }
+
+    /**
+     * Validate the upper bound.
+     *
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code bound} is equal to or less than zero, or
+     * is not finite
+     */
+    static void validateUpperBound(float bound) {
+        // Negation of logic will detect NaN
+        if (!(bound > 0 && bound <= Float.MAX_VALUE)) {
+            throw new IllegalArgumentException(INVALID_UPPER_BOUND + bound);
+        }
+    }
+
+    /**
+     * Validate the upper bound.
+     *
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code bound} is equal to or less than zero, or
+     * is not finite
+     */
+    static void validateUpperBound(double bound) {
+        // Negation of logic will detect NaN
+        if (!(bound > 0 && bound <= Double.MAX_VALUE)) {
+            throw new IllegalArgumentException(INVALID_UPPER_BOUND + bound);
+        }
+    }
+
+    /**
+     * Validate the range between the specified {@code origin} (inclusive) and the
+     * specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     */
+    static void validateRange(int origin, int bound) {
+        if (origin >= bound) {
+            throw new IllegalArgumentException(String.format(INVALID_RANGE, origin, bound));
+        }
+    }
+
+    /**
+     * Validate the range between the specified {@code origin} (inclusive) and the
+     * specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code origin} is greater than or equal to
+     * {@code bound}.
+     */
+    static void validateRange(long origin, long bound) {
+        if (origin >= bound) {
+            throw new IllegalArgumentException(String.format(INVALID_RANGE, origin, bound));
+        }
+    }
+
+    /**
+     * Validate the range between the specified {@code origin} (inclusive) and the
+     * specified {@code bound} (exclusive).
+     *
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned.
+     * @throws IllegalArgumentException if {@code origin} is not finite, or {@code bound}
+     * is not finite, or {@code origin} is greater than or equal to {@code bound}.
+     */
+    static void validateRange(double origin, double bound) {
+        if (origin >= bound || !Double.isFinite(origin) || !Double.isFinite(bound)) {
+            throw new IllegalArgumentException(String.format(INVALID_RANGE, origin, bound));
+        }
+    }
+
+    /**
+     * Checks if the sub-range from fromIndex (inclusive) to fromIndex + size (exclusive) is
+     * within the bounds of range from 0 (inclusive) to length (exclusive).
+     *
+     * <p>This function provides the functionality of
+     * {@code java.utils.Objects.checkFromIndexSize} introduced in JDK 9. The
+     * <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Objects.html#checkFromIndexSize(int,int,int)">Objects</a>
+     * javadoc has been reproduced for reference.
+     *
+     * <p>The sub-range is defined to be out of bounds if any of the following inequalities
+     * is true:
+     * <ul>
+     * <li>{@code fromIndex < 0}
+     * <li>{@code size < 0}
+     * <li>{@code fromIndex + size > length}, taking into account integer overflow
+     * <li>{@code length < 0}, which is implied from the former inequalities
+     * </ul>
+     *
+     * <p>Note: This is not an exact implementation of the functionality of
+     * {@code Objects.checkFromIndexSize}. The following changes have been made:
+     * <ul>
+     * <li>The method signature has been changed to avoid the return of {@code fromIndex};
+     * this value is not used within this package.
+     * <li>No checks are made for {@code length < 0} as this is assumed to be derived from
+     * an array length.
+     * </ul>
+     *
+     * @param fromIndex the lower-bound (inclusive) of the sub-interval
+     * @param size the size of the sub-range
+     * @param length the upper-bound (exclusive) of the range
+     * @throws IndexOutOfBoundsException if the sub-range is out of bounds
+     */
+    static void validateFromIndexSize(int fromIndex, int size, int length) {
+        // check for any negatives (assume 'length' is positive array length),
+        // or overflow safe length check given the values are all positive
+        // remaining = length - fromIndex
+        if ((fromIndex | size) < 0 || size > length - fromIndex) {
+            throw new IndexOutOfBoundsException(
+                // Note: %<d is 'relative indexing' to re-use the last argument
+                String.format("Range [%d, %<d + %d) out of bounds for length %d",
+                    fromIndex, size, length));
+        }
+    }
+
+    /**
+     * Generates random bytes and places them into a user-supplied array.
+     *
+     * <p>The array is filled with bytes extracted from random {@code long} values. This
+     * implies that the number of random bytes generated may be larger than the length of
+     * the byte array.
+     *
+     * @param source Source of randomness.
+     * @param bytes Array in which to put the generated bytes. Cannot be null.
+     * @param start Index at which to start inserting the generated bytes.
+     * @param len Number of bytes to insert.
+     */
+    static void nextBytes(UniformRandomProvider source,
+                          byte[] bytes, int start, int len) {
+        // Index of first insertion plus multiple of 8 part of length
+        // (i.e. length with 3 least significant bits unset).
+        final int indexLoopLimit = start + (len & 0x7ffffff8);
+
+        // Start filling in the byte array, 8 bytes at a time.
+        int index = start;
+        while (index < indexLoopLimit) {
+            final long random = source.nextLong();
+            bytes[index++] = (byte) random;
+            bytes[index++] = (byte) (random >>> 8);
+            bytes[index++] = (byte) (random >>> 16);
+            bytes[index++] = (byte) (random >>> 24);
+            bytes[index++] = (byte) (random >>> 32);
+            bytes[index++] = (byte) (random >>> 40);
+            bytes[index++] = (byte) (random >>> 48);
+            bytes[index++] = (byte) (random >>> 56);
+        }
+
+        // Index of last insertion + 1
+        final int indexLimit = start + len;
+
+        // Fill in the remaining bytes.
+        if (index < indexLimit) {
+            long random = source.nextLong();
+            for (;;) {
+                bytes[index++] = (byte) random;
+                if (index == indexLimit) {
+                    break;
+                }
+                random >>>= 8;
+            }
+        }
+    }
+
+    /**
+     * Generates an {@code int} value between 0 (inclusive) and the specified value
+     * (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param n Bound on the random number to be returned. Must be strictly positive.
+     * @return a random {@code int} value between 0 (inclusive) and {@code n} (exclusive).
+     */
+    static int nextInt(UniformRandomProvider source,
+                       int n) {
+        // Lemire (2019): Fast Random Integer Generation in an Interval
+        // https://arxiv.org/abs/1805.10941
+        long m = (source.nextInt() & 0xffffffffL) * n;
+        long l = m & 0xffffffffL;
+        if (l < n) {
+            // 2^32 % n
+            final long t = POW_32 % n;
+            while (l < t) {
+                m = (source.nextInt() & 0xffffffffL) * n;
+                l = m & 0xffffffffL;
+            }
+        }
+        return (int) (m >>> 32);
+    }
+
+    /**
+     * Generates an {@code int} value between the specified {@code origin} (inclusive) and
+     * the specified {@code bound} (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned. Must be
+     * above {@code origin}.
+     * @return a random {@code int} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     */
+    static int nextInt(UniformRandomProvider source,
+                       int origin, int bound) {
+        final int n = bound - origin;
+        if (n > 0) {
+            return nextInt(source, n) + origin;
+        }
+        // Range too large to fit in a positive integer.
+        // Use simple rejection.
+        int v = source.nextInt();
+        while (v < origin || v >= bound) {
+            v = source.nextInt();
+        }
+        return v;
+    }
+
+    /**
+     * Generates an {@code long} value between 0 (inclusive) and the specified value
+     * (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param n Bound on the random number to be returned. Must be strictly positive.
+     * @return a random {@code long} value between 0 (inclusive) and {@code n}
+     * (exclusive).
+     */
+    static long nextLong(UniformRandomProvider source,
+                         long n) {
+        long bits;
+        long val;
+        do {
+            bits = source.nextLong() >>> 1;
+            val  = bits % n;
+        } while (bits - val + (n - 1) < 0);
+
+        return val;
+    }
+
+    /**
+     * Generates a {@code long} value between the specified {@code origin} (inclusive) and
+     * the specified {@code bound} (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param origin Lower bound on the random number to be returned.
+     * @param bound Upper bound (exclusive) on the random number to be returned. Must be
+     * above {@code origin}.
+     * @return a random {@code long} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     */
+    static long nextLong(UniformRandomProvider source,
+                         long origin, long bound) {
+        final long n = bound - origin;
+        if (n > 0) {
+            return nextLong(source, n) + origin;
+        }
+        // Range too large to fit in a positive integer.
+        // Use simple rejection.
+        long v = source.nextLong();
+        while (v < origin || v >= bound) {
+            v = source.nextLong();
+        }
+        return v;
+    }
+
+    /**
+     * Generates a {@code float} value between 0 (inclusive) and the specified value
+     * (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param bound Bound on the random number to be returned. Must be strictly positive.
+     * @return a random {@code float} value between 0 (inclusive) and {@code bound}
+     * (exclusive).
+     */
+    static float nextFloat(UniformRandomProvider source,
+                           float bound) {
+        float v = source.nextFloat() * bound;
+        if (v >= bound) {
+            // Correct rounding
+            v = Math.nextDown(bound);
+        }
+        return v;
+    }
+
+    /**
+     * Generates a {@code float} value between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param origin Lower bound on the random number to be returned. Must be finite.
+     * @param bound Upper bound (exclusive) on the random number to be returned. Must be
+     * above {@code origin} and finite.
+     * @return a random {@code float} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     */
+    static float nextFloat(UniformRandomProvider source,
+                           float origin, float bound) {
+        float v = source.nextFloat();
+        // This expression allows (bound - origin) to be infinite
+        // origin + (bound - origin) * v
+        // == origin - origin * v + bound * v
+        v = (1f - v) * origin + v * bound;
+        if (v >= bound) {
+            // Correct rounding
+            v = Math.nextDown(bound);
+        }
+        return v;
+    }
+
+    /**
+     * Generates a {@code double} value between 0 (inclusive) and the specified value
+     * (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param bound Bound on the random number to be returned. Must be strictly positive.
+     * @return a random {@code double} value between 0 (inclusive) and {@code bound}
+     * (exclusive).
+     */
+    static double nextDouble(UniformRandomProvider source,
+                             double bound) {
+        double v = source.nextDouble() * bound;
+        if (v >= bound) {
+            // Correct rounding
+            v = Math.nextDown(bound);
+        }
+        return v;
+    }
+
+    /**
+     * Generates a {@code double} value between the specified {@code origin} (inclusive)
+     * and the specified {@code bound} (exclusive).
+     *
+     * @param source Source of randomness.
+     * @param origin Lower bound on the random number to be returned. Must be finite.
+     * @param bound Upper bound (exclusive) on the random number to be returned. Must be
+     * above {@code origin} and finite.
+     * @return a random {@code double} value between {@code origin} (inclusive) and
+     * {@code bound} (exclusive).
+     */
+    static double nextDouble(UniformRandomProvider source,
+                             double origin, double bound) {
+        double v = source.nextDouble();
+        // This expression allows (bound - origin) to be infinite
+        // origin + (bound - origin) * v
+        // == origin - origin * v + bound * v
+        v = (1f - v) * origin + v * bound;
+        if (v >= bound) {
+            // Correct rounding
+            v = Math.nextDown(bound);
+        }
+        return v;
+    }
+}
diff --git a/commons-rng-client-api/src/test/java/org/apache/commons/rng/UniformRandomProviderTest.java b/commons-rng-client-api/src/test/java/org/apache/commons/rng/UniformRandomProviderTest.java
new file mode 100644
index 0000000..0cd7076
--- /dev/null
+++ b/commons-rng-client-api/src/test/java/org/apache/commons/rng/UniformRandomProviderTest.java
@@ -0,0 +1,1114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.SplittableRandom;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.LongSupplier;
+import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+/**
+ * Tests for default method implementations in {@link UniformRandomProvider}.
+ *
+ * <p>This class verifies all exception conditions for the range methods and
+ * the range arguments to the stream methods. Streams methods are asserted
+ * to call the corresponding single value generation method in the interface.
+ * Single value generation methods are asserted using a test of uniformity
+ * from multiple samples.
+ */
+class UniformRandomProviderTest {
+    private static final long STREAM_SIZE_ONE = 1;
+    /** Sample size for statistical uniformity tests. */
+    private static final int SAMPLE_SIZE = 1000;
+    /** Sample size for statistical uniformity tests as a BigDecimal. */
+    private static final BigDecimal SAMPLE_SIZE_BD = BigDecimal.valueOf(SAMPLE_SIZE);
+    /** Relative error used to verify the sum of expected frequencies matches the sample size. */
+    private static final double RELATIVE_ERROR = Math.ulp(1.0) * 2;
+
+    /**
+     * Dummy class for checking the behavior of the UniformRandomProvider.
+     */
+    private static class DummyGenerator implements UniformRandomProvider {
+        /** An instance. */
+        static final DummyGenerator INSTANCE = new DummyGenerator();
+
+        @Override
+        public long nextLong() {
+            throw new UnsupportedOperationException("The nextLong method should not be invoked");
+        }
+    }
+
+    static int[] invalidNextIntBound() {
+        return new int[] {0, -1, Integer.MIN_VALUE};
+    }
+
+    static Stream<Arguments> invalidNextIntOriginBound() {
+        return Stream.of(
+            Arguments.of(1, 1),
+            Arguments.of(2, 1),
+            Arguments.of(-1, -1),
+            Arguments.of(-1, -2)
+        );
+    }
+
+    static long[] invalidNextLongBound() {
+        return new long[] {0, -1, Long.MIN_VALUE};
+    }
+
+    static Stream<Arguments> invalidNextLongOriginBound() {
+        return Stream.of(
+            Arguments.of(1L, 1L),
+            Arguments.of(2L, 1L),
+            Arguments.of(-1L, -1L),
+            Arguments.of(-1L, -2L)
+        );
+    }
+
+    static float[] invalidNextFloatBound() {
+        return new float[] {0, -1, -Float.MAX_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY};
+    }
+
+    static Stream<Arguments> invalidNextFloatOriginBound() {
+        return Stream.of(
+            Arguments.of(1f, 1f),
+            Arguments.of(2f, 1f),
+            Arguments.of(-1f, -1f),
+            Arguments.of(-1f, -2f),
+            Arguments.of(Float.NEGATIVE_INFINITY, 0f),
+            Arguments.of(0f, Float.POSITIVE_INFINITY),
+            Arguments.of(0f, Float.NaN),
+            Arguments.of(Float.NaN, 1f)
+        );
+    }
+
+    static double[] invalidNextDoubleBound() {
+        return new double[] {0, -1, -Double.MAX_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY};
+    }
+
+    static Stream<Arguments> invalidNextDoubleOriginBound() {
+        return Stream.of(
+            Arguments.of(1, 1),
+            Arguments.of(2, 1),
+            Arguments.of(-1, -1),
+            Arguments.of(-1, -2),
+            Arguments.of(Double.NEGATIVE_INFINITY, 0),
+            Arguments.of(0, Double.POSITIVE_INFINITY),
+            Arguments.of(0, Double.NaN),
+            Arguments.of(Double.NaN, 1)
+        );
+    }
+
+    static long[] streamSizes() {
+        return new long[] {0, 1, 13};
+    }
+
+    /**
+     * Creates a functional random generator by implementing the
+     * {@link UniformRandomProvider#nextLong} method with a high quality source of randomness.
+     *
+     * @param seed Seed for the generator.
+     * @return the random generator
+     */
+    private static UniformRandomProvider createRNG(long seed) {
+        // The algorithm for SplittableRandom with the default increment passes:
+        // - Test U01 BigCrush
+        // - PractRand with at least 2^42 bytes (4 TiB) of output
+        return new SplittableRandom(seed)::nextLong;
+    }
+
+    @Test
+    void testNextBytesThrows() {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(NullPointerException.class, () -> rng.nextBytes(null));
+        Assertions.assertThrows(NullPointerException.class, () -> rng.nextBytes(null, 0, 1));
+        // Invalid range
+        final int length = 10;
+        final byte[] bytes = new byte[length];
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.nextBytes(bytes, -1, 1), "start < 0");
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.nextBytes(bytes, length, 1), "start >= length");
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.nextBytes(bytes, 0, -1), "len < 0");
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.nextBytes(bytes, 5, 10), "start + len > length");
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> rng.nextBytes(bytes, 5, Integer.MAX_VALUE), "start + len > length, taking into account integer overflow");
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextIntBound"})
+    void testNextIntBoundThrows(int bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextInt(bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextIntOriginBound"})
+    void testNextIntOriginBoundThrows(int origin, int bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextInt(origin, bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextLongBound"})
+    void testNextLongBoundThrows(long bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextLong(bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextLongOriginBound"})
+    void testNextLongOriginBoundThrows(long origin, long bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextLong(origin, bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextFloatBound"})
+    void testNextFloatBoundThrows(float bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextFloat(bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextFloatOriginBound"})
+    void testNextFloatOriginBoundThrows(float origin, float bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextFloat(origin, bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextDoubleBound"})
+    void testNextDoubleBoundThrows(double bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextDouble(bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextDoubleOriginBound"})
+    void testNextDoubleOriginBoundThrows(double origin, double bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.nextDouble(origin, bound));
+    }
+
+    @Test
+    void testNextFloatExtremes() {
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            private int[] values = {0, -1, 1 << 8};
+            @Override
+            public int nextInt() {
+                return values[i++];
+            }
+        };
+        Assertions.assertEquals(0, rng.nextFloat(), "Expected zero bits to return 0");
+        Assertions.assertEquals(Math.nextDown(1f), rng.nextFloat(), "Expected all bits to return ~1");
+        // Assumes the value is created from the high 24 bits of nextInt
+        Assertions.assertEquals(1f - Math.nextDown(1f), rng.nextFloat(), "Expected 1 bit (shifted) to return ~0");
+    }
+
+    @ParameterizedTest
+    @ValueSource(floats = {Float.MIN_NORMAL, Float.MIN_NORMAL / 2})
+    void testNextFloatBoundRounding(float bound) {
+        // This method will be used
+        final UniformRandomProvider rng = new DummyGenerator() {
+            @Override
+            public float nextFloat() {
+                return Math.nextDown(1.0f);
+            }
+        };
+        Assertions.assertEquals(bound, rng.nextFloat() * bound, "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextFloat(bound), "Result was not correctly rounded down");
+    }
+
+    @Test
+    void testNextFloatOriginBoundInfiniteRange() {
+        // This method will be used
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            private float[] values = {0, 0.25f, 0.5f, 0.75f, 1};
+            @Override
+            public float nextFloat() {
+                return values[i++];
+            }
+        };
+        final float x = Float.MAX_VALUE;
+        Assertions.assertEquals(-x, rng.nextFloat(-x, x));
+        Assertions.assertEquals(-x / 2, rng.nextFloat(-x, x), Math.ulp(x / 2));
+        Assertions.assertEquals(0, rng.nextFloat(-x, x));
+        Assertions.assertEquals(x / 2, rng.nextFloat(-x, x), Math.ulp(x / 2));
+        Assertions.assertEquals(Math.nextDown(x), rng.nextFloat(-x, x));
+    }
+
+    @Test
+    void testNextFloatOriginBoundRounding() {
+        // This method will be used
+        final float v = Math.nextDown(1.0f);
+        final UniformRandomProvider rng = new DummyGenerator() {
+            @Override
+            public float nextFloat() {
+                return v;
+            }
+        };
+        float origin;
+        float bound;
+
+        // Simple case
+        origin = 3.5f;
+        bound = 4.5f;
+        Assertions.assertEquals(bound, origin + v * (bound - origin), "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextFloat(origin, bound), "Result was not correctly rounded down");
+
+        // Alternate formula:
+        // requires sub-normal result for 'origin * v' to force rounding
+        origin = -Float.MIN_NORMAL / 2;
+        bound = Float.MIN_NORMAL / 2;
+        Assertions.assertEquals(bound, origin * (1 - v) + v * bound, "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextFloat(origin, bound), "Result was not correctly rounded down");
+    }
+
+    @Test
+    void testNextDoubleExtremes() {
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            private long[] values = {0, -1, 1L << 11};
+            @Override
+            public long nextLong() {
+                return values[i++];
+            }
+        };
+        Assertions.assertEquals(0, rng.nextDouble(), "Expected zero bits to return 0");
+        Assertions.assertEquals(Math.nextDown(1.0), rng.nextDouble(), "Expected all bits to return ~1");
+        // Assumes the value is created from the high 53 bits of nextInt
+        Assertions.assertEquals(1.0 - Math.nextDown(1.0), rng.nextDouble(), "Expected 1 bit (shifted) to return ~0");
+    }
+
+    @ParameterizedTest
+    @ValueSource(doubles = {Double.MIN_NORMAL, Double.MIN_NORMAL / 2})
+    void testNextDoubleBoundRounding(double bound) {
+        // This method will be used
+        final UniformRandomProvider rng = new DummyGenerator() {
+            @Override
+            public double nextDouble() {
+                return Math.nextDown(1.0);
+            }
+        };
+        Assertions.assertEquals(bound, rng.nextDouble() * bound, "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextDouble(bound), "Result was not correctly rounded down");
+    }
+
+    @Test
+    void testNextDoubleOriginBoundInfiniteRange() {
+        // This method will be used
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            private double[] values = {0, 0.25, 0.5, 0.75, 1};
+            @Override
+            public double nextDouble() {
+                return values[i++];
+            }
+        };
+        final double x = Double.MAX_VALUE;
+        Assertions.assertEquals(-x, rng.nextDouble(-x, x));
+        Assertions.assertEquals(-x / 2, rng.nextDouble(-x, x), Math.ulp(x / 2));
+        Assertions.assertEquals(0, rng.nextDouble(-x, x));
+        Assertions.assertEquals(x / 2, rng.nextDouble(-x, x), Math.ulp(x / 2));
+        Assertions.assertEquals(Math.nextDown(x), rng.nextDouble(-x, x));
+    }
+
+    @Test
+    void testNextDoubleOriginBoundRounding() {
+        // This method will be used
+        final double v = Math.nextDown(1.0);
+        final UniformRandomProvider rng = new DummyGenerator() {
+            @Override
+            public double nextDouble() {
+                return v;
+            }
+        };
+        double origin;
+        double bound;
+
+        // Simple case
+        origin = 3.5;
+        bound = 4.5;
+        Assertions.assertEquals(bound, origin + v * (bound - origin), "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextDouble(origin, bound), "Result was not correctly rounded down");
+
+        // Alternate formula:
+        // requires sub-normal result for 'origin * v' to force rounding
+        origin = -Double.MIN_NORMAL / 2;
+        bound = Double.MIN_NORMAL / 2;
+        Assertions.assertEquals(bound, origin * (1 - v) + v * bound, "Expected result to be rounded up");
+        Assertions.assertEquals(Math.nextDown(bound), rng.nextDouble(origin, bound), "Result was not correctly rounded down");
+    }
+
+    @Test
+    void testNextBooleanIsIntSignBit() {
+        final int size = 10;
+        final int[] values = ThreadLocalRandom.current().ints(size).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public int nextInt() {
+                return values[i++];
+            }
+        };
+        for (int i = 0; i < size; i++) {
+            Assertions.assertEquals(values[i] < 0, rng.nextBoolean());
+        }
+    }
+
+    @ParameterizedTest
+    @ValueSource(longs = {-1, -2, Long.MIN_VALUE})
+    void testInvalidStreamSizeThrows(long size) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.ints(size), "ints");
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.ints(size, 1, 42), "ints(lower, upper)");
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.longs(size), "longs");
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.longs(size, 3L, 33L), "longs(lower, upper)");
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.doubles(size), "doubles");
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.doubles(size, 1.5, 2.75), "doubles(lower, upper)");
+    }
+
+    @Test
+    void testUnlimitedStreamSize() {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertEquals(Long.MAX_VALUE, rng.ints().spliterator().estimateSize(), "ints");
+        Assertions.assertEquals(Long.MAX_VALUE, rng.ints(1, 42).spliterator().estimateSize(), "ints(lower, upper)");
+        Assertions.assertEquals(Long.MAX_VALUE, rng.longs().spliterator().estimateSize(), "longs");
+        Assertions.assertEquals(Long.MAX_VALUE, rng.longs(3L, 33L).spliterator().estimateSize(), "longs(lower, upper)");
+        Assertions.assertEquals(Long.MAX_VALUE, rng.doubles().spliterator().estimateSize(), "doubles");
+        Assertions.assertEquals(Long.MAX_VALUE, rng.doubles(1.5, 2.75).spliterator().estimateSize(), "doubles(lower, upper)");
+    }
+
+    // Test stream methods throw immediately for invalid range arguments.
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextIntOriginBound"})
+    void testIntsOriginBoundThrows(int origin, int bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.ints(origin, bound));
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.ints(STREAM_SIZE_ONE, origin, bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextLongOriginBound"})
+    void testLongsOriginBoundThrows(long origin, long bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.longs(origin, bound));
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.longs(STREAM_SIZE_ONE, origin, bound));
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"invalidNextDoubleOriginBound"})
+    void testDoublesOriginBoundThrows(double origin, double bound) {
+        final UniformRandomProvider rng = DummyGenerator.INSTANCE;
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.doubles(origin, bound));
+        Assertions.assertThrows(IllegalArgumentException.class, () -> rng.doubles(STREAM_SIZE_ONE, origin, bound));
+    }
+
+    // Test stream methods call the correct generation method in the UniformRandomProvider.
+    // If range arguments are supplied they are asserted to be passed through.
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testInts(long streamSize) {
+        final int[] values = ThreadLocalRandom.current().ints(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public int nextInt() {
+                return values[i++];
+            }
+        };
+
+        final IntStream stream = rng.ints();
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testIntsOriginBound(long streamSize) {
+        final int origin = 13;
+        final int bound = 42;
+        final int[] values = ThreadLocalRandom.current().ints(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public int nextInt(int o, int b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final IntStream stream = rng.ints(origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testIntsWithSize(long streamSize) {
+        final int[] values = ThreadLocalRandom.current().ints(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public int nextInt() {
+                return values[i++];
+            }
+        };
+
+        final IntStream stream = rng.ints(streamSize);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testIntsOriginBoundWithSize(long streamSize) {
+        final int origin = 13;
+        final int bound = 42;
+        final int[] values = ThreadLocalRandom.current().ints(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public int nextInt(int o, int b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final IntStream stream = rng.ints(streamSize, origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testLongs(long streamSize) {
+        final long[] values = ThreadLocalRandom.current().longs(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public long nextLong() {
+                return values[i++];
+            }
+        };
+
+        final LongStream stream = rng.longs();
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testLongsOriginBound(long streamSize) {
+        final long origin = 13;
+        final long bound = 42;
+        final long[] values = ThreadLocalRandom.current().longs(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public long nextLong(long o, long b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final LongStream stream = rng.longs(origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testLongsWithSize(long streamSize) {
+        final long[] values = ThreadLocalRandom.current().longs(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public long nextLong() {
+                return values[i++];
+            }
+        };
+
+        final LongStream stream = rng.longs(streamSize);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testLongsOriginBoundWithSize(long streamSize) {
+        final long origin = 13;
+        final long bound = 42;
+        final long[] values = ThreadLocalRandom.current().longs(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public long nextLong(long o, long b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final LongStream stream = rng.longs(streamSize, origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testDoubles(long streamSize) {
+        final double[] values = ThreadLocalRandom.current().doubles(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public double nextDouble() {
+                return values[i++];
+            }
+        };
+
+        final DoubleStream stream = rng.doubles();
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testDoublesOriginBound(long streamSize) {
+        final double origin = 13;
+        final double bound = 42;
+        final double[] values = ThreadLocalRandom.current().doubles(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public double nextDouble(double o, double b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final DoubleStream stream = rng.doubles(origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.limit(streamSize).toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testDoublesWithSize(long streamSize) {
+        final double[] values = ThreadLocalRandom.current().doubles(streamSize).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public double nextDouble() {
+                return values[i++];
+            }
+        };
+
+        final DoubleStream stream = rng.doubles(streamSize);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    @ParameterizedTest
+    @MethodSource(value = {"streamSizes"})
+    void testDoublesOriginBoundWithSize(long streamSize) {
+        final double origin = 13;
+        final double bound = 42;
+        final double[] values = ThreadLocalRandom.current().doubles(streamSize, origin, bound).toArray();
+        final UniformRandomProvider rng = new DummyGenerator() {
+            private int i;
+            @Override
+            public double nextDouble(double o, double b) {
+                Assertions.assertEquals(origin, o, "origin");
+                Assertions.assertEquals(bound, b, "bound");
+                return values[i++];
+            }
+        };
+
+        final DoubleStream stream = rng.doubles(streamSize, origin, bound);
+        Assertions.assertFalse(stream.isParallel());
+        Assertions.assertArrayEquals(values, stream.toArray());
+    }
+
+    // Statistical tests for uniform distribution
+
+    // Monobit tests
+
+    @ParameterizedTest
+    @ValueSource(longs = {263784628482L, -2563472, -2367482842368L})
+    void testNextIntMonobit(long seed) {
+        final UniformRandomProvider rng = createRNG(seed);
+        int bitCount = 0;
+        final int n = 100;
+        for (int i = 0; i < n; i++) {
+            bitCount += Integer.bitCount(rng.nextInt());
+        }
+        final int numberOfBits = n * Integer.SIZE;
+        assertMonobit(bitCount, numberOfBits);
+    }
+
+    @ParameterizedTest
+    @ValueSource(longs = {263784628L, 253674, -23568426834L})
+    void testNextDoubleMonobit(long seed) {
+        final UniformRandomProvider rng = createRNG(seed);
+        int bitCount = 0;
+        final int n = 100;
+        for (int i = 0; i < n; i++) {
+            bitCount += Long.bitCount((long) (rng.nextDouble() * (1L << 53)));
+        }
+        final int numberOfBits = n * 53;
+        assertMonobit(bitCount, numberOfBits);
+    }
+
+    @ParameterizedTest
+    @ValueSource(longs = {265342L, -234232, -672384648284L})
+    void testNextBooleanMonobit(long seed) {
+        final UniformRandomProvider rng = createRNG(seed);
+        int bitCount = 0;
+        final int n = 1000;
+        for (int i = 0; i < n; i++) {
+            if (rng.nextBoolean()) {
+                bitCount++;
+            }
+        }
+        final int numberOfBits = n;
+        assertMonobit(bitCount, numberOfBits);
+    }
+
+    @ParameterizedTest
+    @ValueSource(longs = {-1526731, 263846, 4545})
+    void testNextFloatMonobit(long seed) {
+        final UniformRandomProvider rng = createRNG(seed);
+        int bitCount = 0;
+        final int n = 100;
+        for (int i = 0; i < n; i++) {
+            bitCount += Integer.bitCount((int) (rng.nextFloat() * (1 << 24)));
+        }
+        final int numberOfBits = n * 24;
+        assertMonobit(bitCount, numberOfBits);
+    }
+
+    @ParameterizedTest
+    @CsvSource({
+        "-2638468223894, 16",
+        "235647674, 17",
+        "-928738475, 23",
+    })
+    void testNextBytesMonobit(long seed, int range) {
+        final UniformRandomProvider rng = createRNG(seed);
+        final byte[] bytes = new byte[range];
+        int bitCount = 0;
+        final int n = 100;
+        for (int i = 0; i < n; i++) {
+            rng.nextBytes(bytes);
+            for (final byte b1 : bytes) {
+                bitCount += Integer.bitCount(b1 & 0xff);
+            }
+        }
+        final int numberOfBits = n * Byte.SIZE * range;
+        assertMonobit(bitCount, numberOfBits);
+    }
+
+    /**
+     * Assert that the number of 1 bits is approximately 50%. This is based upon a
+     * fixed-step "random walk" of +1/-1 from zero.
+     *
+     * <p>The test is equivalent to the NIST Monobit test with a fixed p-value of
+     * 0.01. The number of bits is recommended to be above 100.</p>
+     *
+     * @see <A
+     * href="https://csrc.nist.gov/publications/detail/sp/800-22/rev-1a/final">Bassham,
+     * et al (2010) NIST SP 800-22: A Statistical Test Suite for Random and
+     * Pseudorandom Number Generators for Cryptographic Applications. Section
+     * 2.1.</a>
+     *
+     * @param bitCount The bit count.
+     * @param numberOfBits Number of bits.
+     */
+    private static void assertMonobit(int bitCount, int numberOfBits) {
+        // Convert the bit count into a number of +1/-1 steps.
+        final double sum = 2.0 * bitCount - numberOfBits;
+        // The reference distribution is Normal with a standard deviation of sqrt(n).
+        // Check the absolute position is not too far from the mean of 0 with a fixed
+        // p-value of 0.01 taken from a 2-tailed Normal distribution. Computation of
+        // the p-value requires the complimentary error function.
+        final double absSum = Math.abs(sum);
+        final double max = Math.sqrt(numberOfBits) * 2.5758293035489004;
+        Assertions.assertTrue(absSum <= max,
+            () -> "Walked too far astray: " + absSum + " > " + max +
+                  " (test will fail randomly about 1 in 100 times)");
+    }
+
+    // Uniformity tests
+
+    @ParameterizedTest
+    @CsvSource({
+        "263746283, 23, 0, 23",
+        "-126536861889, 16, 0, 16",
+        "617868181124, 1234, 567, 89",
+        "-56788, 512, 0, 233",
+        "6787535424, 512, 233, 279",
+    })
+    void testNextBytesUniform(long seed,
+                              int length, int start, int size) {
+        final UniformRandomProvider rng = createRNG(seed);
+        final byte[] buffer = new byte[length];
+
+        final Runnable nextMethod = start == 0 && size == length ?
+                () -> rng.nextBytes(buffer) :
+                () -> rng.nextBytes(buffer, start, size);
+
+        final int last = start + size;
+        Assertions.assertTrue(isUniformNextBytes(buffer, start, last, nextMethod),
+                              "Expected uniform bytes");
+
+        // The parts of the buffer where no values are put should be zero.
+        for (int i = 0; i < start; i++) {
+            Assertions.assertEquals(0, buffer[i], () -> "Filled < start: " + start);
+        }
+        for (int i = last; i < length; i++) {
+            Assertions.assertEquals(0, buffer[i], () -> "Filled >= last: " + last);
+        }
+    }
+
+    /**
+     * Checks that the generator values can be placed into 256 bins with
+     * approximately equal number of counts.
+     * Test allows to select only part of the buffer for performing the
+     * statistics.
+     *
+     * @param buffer Buffer to be filled.
+     * @param first First element (included) of {@code buffer} range for
+     * which statistics must be taken into account.
+     * @param last Last element (excluded) of {@code buffer} range for
+     * which statistics must be taken into account.
+     * @param nextMethod Method that fills the given {@code buffer}.
+     * @return {@code true} if the distribution is uniform.
+     */
+    private static boolean isUniformNextBytes(byte[] buffer,
+                                              int first,
+                                              int last,
+                                              Runnable nextMethod) {
+        final int sampleSize = 10000;
+
+        // Number of possible values (do not change).
+        final int byteRange = 256;
+        // Chi-square critical value with 255 degrees of freedom
+        // and 1% significance level.
+        final double chi2CriticalValue = 310.45738821990585;
+
+        // Bins.
+        final long[] observed = new long[byteRange];
+        final double[] expected = new double[byteRange];
+
+        Arrays.fill(expected, sampleSize * (last - first) / (double) byteRange);
+
+        for (int k = 0; k < sampleSize; k++) {
+            nextMethod.run();
+
+            for (int i = first; i < last; i++) {
+                // Convert byte to an index in [0, 255]
+                ++observed[buffer[i] & 0xff];
+            }
+        }
+
+        // Compute chi-square.
+        double chi2 = 0;
+        for (int k = 0; k < byteRange; k++) {
+            final double diff = observed[k] - expected[k];
+            chi2 += diff * diff / expected[k];
+        }
+
+        // Statistics check.
+        return chi2 <= chi2CriticalValue;
+    }
+
+    // Add range tests
+
+    @ParameterizedTest
+    @CsvSource({
+        // No lower bound
+        "2673846826, 0, 10",
+        "-23658268, 0, 12",
+        "263478624, 0, 31",
+        "1278332, 0, 32",
+        "99734765, 0, 2016128993",
+        "-63485384, 0, 1834691456",
+        "3876457638, 0, 869657561",
+        "-126784782, 0, 1570504788",
+        "2637846, 0, 2147483647",
+        // Small range
+        "2634682, 567576, 567586",
+        "-56757798989, -1000, -100",
+        "-97324785, -54656, 12",
+        "23423235, -526783468, 257",
+        // Large range
+        "-2634682, -1073741824, 1073741824",
+        "6786868132, -1263842626, 1237846372",
+        "-263846723, -368268, 2147483647",
+        "7352352, -2147483648, 61523457",
+    })
+    void testNextIntUniform(long seed, int origin, int bound) {
+        final UniformRandomProvider rng = createRNG(seed);
+        final LongSupplier nextMethod = origin == 0 ?
+                () -> rng.nextInt(bound) :
+                () -> rng.nextInt(origin, bound);
+        checkNextInRange("nextInt", origin, bound, nextMethod);
+    }
+
+    @ParameterizedTest
+    @CsvSource({
+        // No lower bound
+        "2673846826, 0, 11",
+        "-23658268, 0, 19",
+        "263478624, 0, 31",
+        "1278332, 0, 32",
+        "99734765, 0, 2326378468282368421",
+        "-63485384, 0, 4872347624242243222",
+        "3876457638, 0, 6263784682638866843",
+        "-126784782, 0, 7256684297832668332",
+        "2637846, 0, 9223372036854775807",
+        // Small range
+        "2634682, 567576, 567586",
+        "-56757798989, -1000, -100",
+        "-97324785, -54656, 12",
+        "23423235, -526783468, 257",
+        // Large range
+        "-2634682, -4611686018427387904, 4611686018427387904",
+        "6786868132, -4962836478223688590, 6723648246224929947",
+        "-263846723, -368268, 9223372036854775807",
+        "7352352, -9223372036854775808, 61523457",
+    })
+    void testNextLongUniform(long seed, long origin, long bound) {
+        final UniformRandomProvider rng = createRNG(seed);
+        final LongSupplier nextMethod = origin == 0 ?
+                () -> rng.nextLong(bound) :
+                () -> rng.nextLong(origin, bound);
+        checkNextInRange("nextLong", origin, bound, nextMethod);
+    }
+
+    @ParameterizedTest
+    @CsvSource({
+        // Note: If the range limits are integers above 2^24 (16777216) it is not possible
+        // to represent all the values with a float. This has no effect on sampling into bins
+        // but should be avoided when generating integers for use in production code.
+
+        // No lower bound.
+        "2673846826, 0, 11",
+        "-23658268, 0, 19",
+        "263478624, 0, 31",
+        "1278332, 0, 32",
+        "99734765, 0, 1234",
+        "-63485384, 0, 578",
+        "3876457638, 0, 10000",
+        "-126784782, 0, 2983423",
+        "2637846, 0, 16777216",
+        // Range
+        "2634682, 567576, 567586",
+        "-56757798989, -1000, -100",
+        "-97324785, -54656, 12",
+        "23423235, -526783468, 257",
+        "-2634682, -688689797, -516827",
+        "6786868132, -67, 67",
+        "-263846723, -5678, 42",
+        "7352352, 678687, 61523457",
+    })
+    void testNextFloatUniform(long seed, float origin, float bound) {
+        Assertions.assertEquals((long) origin, origin, "origin");
+        Assertions.assertEquals((long) bound, bound, "bound");
+        final UniformRandomProvider rng = createRNG(seed);
+        // Note casting as long will round towards zero.
+        // If the upper bound is negative then this can create a domain error so use floor.
+        final LongSupplier nextMethod = origin == 0 ?
+                () -> (long) rng.nextFloat(bound) :
+                () -> (long) Math.floor(rng.nextFloat(origin, bound));
+        checkNextInRange("nextFloat", (long) origin, (long) bound, nextMethod);
+    }
+
+
+    @ParameterizedTest
+    @CsvSource({
+        // Note: If the range limits are integers above 2^53 (9007199254740992) it is not possible
+        // to represent all the values with a double. This has no effect on sampling into bins
+        // but should be avoided when generating integers for use in production code.
+
+        // No lower bound.
+        "2673846826, 0, 11",
+        "-23658268, 0, 19",
+        "263478624, 0, 31",
+        "1278332, 0, 32",
+        "99734765, 0, 1234",
+        "-63485384, 0, 578",
+        "3876457638, 0, 10000",
+        "-126784782, 0, 2983423",
+        "2637846, 0, 9007199254740992",
+        // Range
+        "2634682, 567576, 567586",
+        "-56757798989, -1000, -100",
+        "-97324785, -54656, 12",
+        "23423235, -526783468, 257",
+        "-2634682, -688689797, -516827",
+        "6786868132, -67, 67",
+        "-263846723, -5678, 42",
+        "7352352, 678687, 61523457",
+    })
+    void testNextDoubleUniform(long seed, double origin, double bound) {
+        Assertions.assertEquals((long) origin, origin, "origin");
+        Assertions.assertEquals((long) bound, bound, "bound");
+        final UniformRandomProvider rng = createRNG(seed);
+        // Note casting as long will round towards zero.
+        // If the upper bound is negative then this can create a domain error so use floor.
+        final LongSupplier nextMethod = origin == 0 ?
+                () -> (long) rng.nextDouble(bound) :
+                () -> (long) Math.floor(rng.nextDouble(origin, bound));
+        checkNextInRange("nextDouble", (long) origin, (long) bound, nextMethod);
+    }
+
+    /**
+     * Tests uniformity of the distribution produced by the given
+     * {@code nextMethod}.
+     * It performs a chi-square test of homogeneity of the observed
+     * distribution with the expected uniform distribution.
+     * Repeat tests are performed at the 1% level and the total number of failed
+     * tests is tested at the 0.5% significance level.
+     *
+     * @param method Generator method.
+     * @param origin Lower bound (inclusive).
+     * @param bound Upper bound (exclusive).
+     * @param nextMethod method to call.
+     */
+    private static void checkNextInRange(String method,
+                                         long origin,
+                                         long bound,
+                                         LongSupplier nextMethod) {
+        // Do not change
+        // (statistical test assumes that 500 repeats are made with dof = 9).
+        final int numTests = 500;
+        final int numBins = 10; // dof = numBins - 1
+
+        // Set up bins.
+        final long[] binUpperBounds = new long[numBins];
+        // Range may be above a positive long: step = (bound - origin) / bins
+        final BigDecimal range = BigDecimal.valueOf(bound)
+                .subtract(BigDecimal.valueOf(origin));
+        final double step = range.divide(BigDecimal.TEN).doubleValue();
+        for (int k = 1; k < numBins; k++) {
+            binUpperBounds[k - 1] = origin + (long) (k * step);
+        }
+        // Final bound
+        binUpperBounds[numBins - 1] = bound;
+
+        // Create expected frequencies
+        final double[] expected = new double[numBins];
+        long previousUpperBound = origin;
+        final double scale = SAMPLE_SIZE_BD.divide(range, MathContext.DECIMAL128).doubleValue();
+        double sum = 0;
+        for (int k = 0; k < numBins; k++) {
+            final long binWidth = binUpperBounds[k] - previousUpperBound;
+            expected[k] = scale * binWidth;
+            sum += expected[k];
+            previousUpperBound = binUpperBounds[k];
+        }
+        Assertions.assertEquals(SAMPLE_SIZE, sum, SAMPLE_SIZE * RELATIVE_ERROR, "Invalid expected frequencies");
+
+        final int[] observed = new int[numBins];
+        // Chi-square critical value with 9 degrees of freedom
+        // and 1% significance level.
+        final double chi2CriticalValue = 21.665994333461924;
+
+        // For storing chi2 larger than the critical value.
+        final List<Double> failedStat = new ArrayList<>();
+        try {
+            final int lastDecileIndex = numBins - 1;
+            for (int i = 0; i < numTests; i++) {
+                Arrays.fill(observed, 0);
+                SAMPLE: for (int j = 0; j < SAMPLE_SIZE; j++) {
+                    final long value = nextMethod.getAsLong();
+                    if (value < origin) {
+                        Assertions.fail(String.format("Sample %d not within bound [%d, %d)",
+                                                      value, origin, bound));
+                    }
+
+                    for (int k = 0; k < lastDecileIndex; k++) {
+                        if (value < binUpperBounds[k]) {
+                            ++observed[k];
+                            continue SAMPLE;
+                        }
+                    }
+                    if (value >= bound) {
+                        Assertions.fail(String.format("Sample %d not within bound [%d, %d)",
+                                                      value, origin, bound));
+                    }
+                    ++observed[lastDecileIndex];
+                }
+
+                // Compute chi-square.
+                double chi2 = 0;
+                for (int k = 0; k < numBins; k++) {
+                    final double diff = observed[k] - expected[k];
+                    chi2 += diff * diff / expected[k];
+                }
+
+                // Statistics check.
+                if (chi2 > chi2CriticalValue) {
+                    failedStat.add(chi2);
+                }
+            }
+        } catch (Exception e) {
+            // Should never happen.
+            throw new RuntimeException("Unexpected", e);
+        }
+
+        // The expected number of failed tests can be modelled as a Binomial distribution
+        // B(n, p) with n=500, p=0.01 (500 tests with a 1% significance level).
+        // The cumulative probability of the number of failed tests (X) is:
+        // x     P(X>x)
+        // 10    0.0132
+        // 11    0.00521
+        // 12    0.00190
+
+        if (failedStat.size() > 11) { // Test will fail with 0.5% probability
+            Assertions.fail(String.format(
+                "%s: Too many failures for n = %d, sample size = %d " +
+                "(%d out of %d tests failed, chi2 > %.3f=%s)",
+                method, bound, SAMPLE_SIZE, failedStat.size(), numTests, chi2CriticalValue,
+                failedStat.stream().map(d -> String.format("%.3f", d))
+                          .collect(Collectors.joining(", ", "[", "]"))));
+        }
+    }
+}
diff --git a/src/main/resources/pmd/pmd-ruleset.xml b/src/main/resources/pmd/pmd-ruleset.xml
index af457bb..ae95f65 100644
--- a/src/main/resources/pmd/pmd-ruleset.xml
+++ b/src/main/resources/pmd/pmd-ruleset.xml
@@ -120,7 +120,8 @@
         value="//ClassOrInterfaceDeclaration[@SimpleName='ListSampler' or @SimpleName='ProviderBuilder'
           or @SimpleName='ThreadLocalRandomSource' or @SimpleName='SeedFactory'
           or @SimpleName='Coordinates' or @SimpleName='Hex' or @SimpleName='SpecialMath'
-          or @SimpleName='Conversions' or @SimpleName='MixFunctions' or @SimpleName='LXMSupport']"/>
+          or @SimpleName='Conversions' or @SimpleName='MixFunctions' or @SimpleName='LXMSupport'
+          or @SimpleName='UniformRandomProviderSupport']"/>
       <!-- Allow samplers to have only factory constructors -->
       <property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]+(Utils?|Helper|Sampler)" />
     </properties>
