/**
   * Generates a random value from this distribution.
   *
   * @return the random value.
   * @throws IllegalStateException if the distribution has not been loaded
   */
  public double getNextValue() throws IllegalStateException {

    if (!loaded) {
      throw MathRuntimeException.createIllegalStateException("distribution not loaded");
    }

    // Start with a uniformly distributed random number in (0,1)
    double x = Math.random();

    // Use this to select the bin and generate a Gaussian within the bin
    for (int i = 0; i < binCount; i++) {
      if (x <= upperBounds[i]) {
        SummaryStatistics stats = binStats.get(i);
        if (stats.getN() > 0) {
          if (stats.getStandardDeviation() > 0) { // more than one obs
            return randomData.nextGaussian(stats.getMean(), stats.getStandardDeviation());
          } else {
            return stats.getMean(); // only one obs in bin
          }
        }
      }
    }
    throw new MathRuntimeException("no bin selected");
  }