@Override
    public Result run() {
        Result result = null;
        try {
            Equals<Double> criterion = this.getCriterion();
            Function<Double, Double> function = this.getFunction();
            double goalValue = this.getGoalValue();
            double value = this.getInitialValue();
            int maxIter = this.getMaximumIterations();
            int iterations = 0;
            double output = function.value(value);
            for (iterations = 0; iterations < maxIter
                    && !criterion.value(output, goalValue);
                    iterations++) {
                output = function.value(value);
                double denominator = this._differentiator.value(value, function);
                if (denominator == 0.0) {
                    result = new SlopeEqualsZeroFailure<Double>(value);
                } else {
                    value -= (output - this.getGoalValue())
                            / denominator;
                }
            }
            if (result == null) {
                if (maxIter <= iterations) {
                    result = new MaximumIterationsFailure(iterations);
                } else {
                    result = new IterativeSuccess<Double>(iterations, value);
                }
            }
        } catch (Exception e) {
            result = new UnhandledExceptionThrown(e);
        }
        return result;
    }