in objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/resolvedmodel/expressionparser/ExpressionTree.java [217:310]
    public static Object evaluateExpressionTree(Node top, InputValues inputValues) {
        if (top == null) {
            return false;
        }
        Object leftReturn = false, rightReturn = false;
        if (top.getLeft() != null) {
            leftReturn = evaluateExpressionTree(top.getLeft(), inputValues);
        }
        if (top.getRight() != null) {
            rightReturn = evaluateExpressionTree(top.getRight(), inputValues);
        }
        if (top.getValueType() == PredefinedType.Custom) {
            // check if number and return number
            try {
                int num = Integer.parseInt((String) top.getValue());
                return num;
            } catch (NumberFormatException e) {
            }
            // check if bool and return bool
            if (((String) top.getValue()).trim().equalsIgnoreCase("true") || ((String) top.getValue()).trim().equalsIgnoreCase("false")) {
                return Boolean.parseBoolean(((String) top.getValue()).trim());
            }
        }
        if (!textToTokenHash.containsKey(top.getValue())) {
            return top.getValue();
        } else {
            switch (textToTokenHash.get(top.getValue())) {
                case AND:
                    return (leftReturn == null || rightReturn == null) ? false : (boolean) leftReturn && (boolean) rightReturn;
                case NOT:
                    return (rightReturn == null) ? false : !((boolean) rightReturn);
                case OR:
                    return (leftReturn == null || rightReturn == null) ? false : (boolean) leftReturn || (boolean) rightReturn;
                case GT:
                    return (leftReturn == null || rightReturn == null) ? false : (int) leftReturn > (int) rightReturn;
                case LT:
                    return (leftReturn == null || rightReturn == null) ? false : (int) leftReturn < (int) rightReturn;
                case GE:
                    return (leftReturn == null || rightReturn == null) ? false : (int) leftReturn >= (int) rightReturn;
                case LE:
                    return (leftReturn == null || rightReturn == null) ? false : (int) leftReturn <= (int) rightReturn;
                case EQ:
                    return convertToTypeAndCheckEquality(leftReturn, rightReturn);
                case NE:
                    return convertToTypeAndCheckInequality(leftReturn, rightReturn);
                case TRUE:
                    return true;
                case FALSE:
                    return false;
                case OPENPAREN:
                case CLOSEPAREN:
                    return true;
                case DEPTH:
                    return inputValues.getNextDepth();
                case MAXDEPTH:
                    return inputValues.getMaxDepth();
                case ISARRAY:
                    return inputValues.getIsArray();
                case NOMAXDEPTH:
                    return inputValues.getNoMaxDepth();
                case MINCARDINALITY:
                    return inputValues.getMinCardinality();
                case MAXCARDINALITY:
                    return inputValues.getMaxCardinality();
                case NORMALIZED:
                    return inputValues.getNormalized();
                case REFERENCEONLY:
                    return inputValues.getReferenceOnly();
                case STRUCTURED:
                    return inputValues.getStructured();
                case VIRTUAL:
                    return inputValues.getIsVirtual();
                case ALWAYS:
                    return true;
                default:
                    return top.getValue();
            }
        }
    }