code: String evaluateExpression(String expr) throws ConfigEvaluatorException {
          ConfigExpressionScanner scanner = new ConfigExpressionScanner(expr);
  
          // Expression   = Arithmetic | FilterCall
          // Arithmetic   = Operand [( "+" | "-" | "*" | "/") Operand]*
          // Operand      = VarName | Long | FunctionCall
          // VarName      = <Java identifier plus "." after start>
          // Long         = <[0-9]+ handled by Long.parseLong>
          // FunctionCall = FunctionName "(" VarName ")"
          // FunctionName = "count"
          // FilterCall   = "servicePidOrFilter(" VarName ")"
  
          // Parse the first operand (or function name).
          if (!parseOperand(expr, scanner, true)) {
              return null;
          }
          if (resultExpr != null) {
              return scanner.end() ? resultExpr : null;
          }
  
          subtotal = value;
  
          while (!scanner.end()) {
              // Parse operator.
              ConfigExpressionScanner.NumericOperator op = scanner.scanNumericOperator();
              if (op == null) {
                  return null;
              }
  
              if (!parseOperand(expr, scanner, false) || (resultExpr != null)) {
                  return null;
              }
  
              subtotal = op.evaluate(subtotal, value);
  
          }
  
          return String.valueOf(subtotal);
      }
docs: Evaluate a variable expression.
  
  @param expr the expression string (for example, "x+0")
  @param context
  @return the result, or null if the evaluation fails because the string
  cannot be parsed, a referenced property does not exist, or some
  other detectable errors occurs
  @throws ConfigEvaluatorException if getPropertyObject fails
  @throws NumberFormatException if a property contains a value that cannot
  be parsed as a Long, or a literal with a too large number
  @throws ArithmeticException if a division error occurs