@Override
    public Result value(final Function<Double, Double> function) {
        Result result = null;
        try
        {
            HashMap<Integer, Double> values = new HashMap<Integer, Double>();
            double lowerBound = this.getRegion().getLowerBound();
            double length = this.getRegion().getUpperBound() - lowerBound;
            int innerMax = this.getInitialSplits();
            final int iterativeSplits = this.getIterativeSplits();
            length /= (double)innerMax;

            int iteration = 0;
            for (iteration = 0; iteration < this.getMaximumIterations() &&
                    !this._HasConverged(values); iteration++) {
                Interval<Double> t = new IntervalReal(
                        lowerBound, Interval.EndType.Includes,
                        lowerBound + length, Interval.EndType.Includes);

                double i = 0;
                for (int j = 0; j < innerMax; j++) {
                    i += this.getEvaluator().value(function, t);
                    this._ShiftInterval(t, length, lowerBound, j);
                }

                values.put(iteration, i);
                innerMax *= iterativeSplits;
                length /= iterativeSplits;
            }
            if (this._HasConverged(values))
                result = new IterativeSuccess(iteration, values.get(iteration - 1));
            else if (this.getMaximumIterations() <= iteration)
                result = new MaximumIterationsFailure(iteration);
            else
                throw new ArithmeticException("Unknown termination: " +
                        "Values have not converged and maximum iterations " +
                        "have not been reached.");
        }
        catch (Exception e)
        { result = new UnhandledExceptionThrown(e); }
        return result;
    }