class JsonPathExpression implements Expression {

    @Override
    public ExpressionResult apply(ExpressionContext expressionContext, ExpressionResult input) {
        ExpressionResult doc = document.apply(expressionContext, input);
        String json = jsonPath.apply(expressionContext, input).getValue().toString();
        Object result = JsonPath.compile(json).read(doc.asJson());
        List<ExpressionResult> values = new ArrayList<>();
        boolean isList = false;
        if( result instanceof JSONArray) {
            isList = true;
            JSONArray resultArray = (JSONArray)result;
            resultArray.forEach(value ->  values.add(toExpressionResult(value)));
        } else {
            values.add(toExpressionResult(result));
        }
        if( ! isList) {
            if( values.size() == 1 ) return values.get(0);
            return NullExpressionResult.INSTANCE;
        }
        return new ListExpressionResult(values);
    }

    public  JsonPathExpression(String alias, Expression[] expressions);

}