public FEELFnResult<Range> invoke(@ParameterName("from") String from) {
        if (from == null || from.isEmpty() || from.isBlank()) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "cannot be null"));
        }
        Range.RangeBoundary startBoundary;
        if (from.startsWith("(") || from.startsWith("]")) {
            startBoundary = RangeBoundary.OPEN;
        } else if (from.startsWith("[")) {
            startBoundary = RangeBoundary.CLOSED;
        } else {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "does not start with a valid character"));
        }
        Range.RangeBoundary endBoundary;
        if (from.endsWith(")") || from.endsWith("[")) {
            endBoundary = RangeBoundary.OPEN;
        } else if (from.endsWith("]")) {
            endBoundary = RangeBoundary.CLOSED;
        } else {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "does not end with a valid character"));
        }

        String[] split = from.split("\\.\\.");
        if (split.length != 2) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "does not include two literals separated by `..` two dots characters"));
        }
        String leftString = split[0].substring(1);
        String rightString = split[1].substring(0, split[1].length() - 1);
        if ((leftString.isEmpty() || leftString.isBlank()) && (rightString.isEmpty() || rightString.isBlank())) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "at least one endpoint must not be null"));
        }
        BaseNode leftNode = parse(leftString);
        if (!nodeIsAllowed(leftNode)) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "left endpoint is not a recognised valid literal"));
        }
        BaseNode rightNode = parse(rightString);
        if (!nodeIsAllowed(rightNode)) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "right endpoint is not a recognised valid literal"));
        }
        Object left = leftNode.evaluate(getStubbed());
        if (!nodeValueIsAllowed(left)) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "left endpoint is not a valid value " + left.getClass()));
        }

        Object right = rightNode.evaluate(getStubbed());
        if (!nodeValueIsAllowed(right)) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "right endpoint is not a valid value " + right.getClass()));
        }

        if (!nodesReturnsSameType(left, right)) {
            return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "from", "endpoints must be of equivalent types"));
        }

        return FEELFnResult.ofResult(new RangeImpl(startBoundary, (Comparable) left, (Comparable) right, endBoundary));
    }
@Test
    void invoke_WithOneFunctionNode() {
        String from = "[number(\"1\", \",\", \".\")\"..2]";
        FunctionTestUtil.assertResult(rangeFunction.invoke(from),
                                      new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.ONE, BigDecimal.valueOf(2)
                                              , Range.RangeBoundary.CLOSED),
                                      from);
        from = "[\"a\"..lower case(\"Z\")]";
        FunctionTestUtil.assertResult(rangeFunction.invoke(from),
                                      new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.CLOSED),
                                      from);
    }