@Override
    public Result run() {
        Result result = null;
        try {
            Equals<Double> criterion = this.getCriterion();
            Function<Double, Double> value = this.getFunction();
            double goalValue = this.getGoalValue();
            int maxIter = this.getMaximumIterations();
            double x_1 = this.getInitialValue().getLowerBound();
            double fx_1 = value.value(x_1);
            if (criterion.value(fx_1, goalValue))
                return new SuccessWithValue(x_1);
            double x = this.getInitialValue().getUpperBound();
            double fx = value.value(x);
            if (criterion.value(fx, goalValue))
                return new SuccessWithValue(x);
            int iter;
            for (iter = 0; iter < maxIter &&
                    !criterion.value(fx, goalValue); iter++) {
                double n = x - (fx - goalValue) * (x - x_1) / (fx - fx_1);
                double fn = value.value(n);
                x_1 = x;
                fx_1 = fx;
                if (x == n)
                    result = new ResolutionNotFineEnough(value,
                            new IntervalReal(
                            Math.min(x_1, n), Interval.EndType.Includes,
                            Math.max(x_1, n), Interval.EndType.Includes),
                            goalValue);
                x = n;
                fx = fn;
            }
            if (result == null) {
                if (maxIter <= iter)
                    result = new MaximumIterationsFailure(iter);
                else
                    result = new IterativeSuccess(iter, x);
            }
        }
        catch (Exception e) {
            result = new UnhandledExceptionThrown(e);
        }
        return result;
    }