private Object apply(OExpression expression, Map<String, Object> input, OCommandContext ctx, int recursion) {
OResultInternal result = new OResultInternal();
if (starItem != null || includeItems.size() == 0) {
for (String property : input.keySet()) {
if (isExclude(property)) {
continue;
}
result.setProperty(property, convert(tryExpand(expression, property, input.get(property), ctx, recursion)));
}
}
if (includeItems.size() > 0) {
for (ONestedProjectionItem item : includeItems) {
String alias = item.alias != null ? item.alias.getStringValue() : item.expression.getDefaultAlias().getStringValue();
OResultInternal elem = new OResultInternal();
input.entrySet().forEach(x -> elem.setProperty(x.getKey(), x.getValue()));
Object value = item.expression.execute(elem, ctx);
if (item.expansion != null) {
value = item.expand(expression, alias, value, ctx, recursion - 1);
}
result.setProperty(alias, convert(value));
}
}
return result;
}