docs: private ModelNode resolveExpressionStringRecursively(final String expressionString, final boolean ignoreDMRResolutionFailure,
                                                           final boolean initial) throws OperationFailedException {
          ParseAndResolveResult resolved = parseAndResolve(expressionString, ignoreDMRResolutionFailure);
          if (resolved.recursive) {
              // Some part of expressionString resolved into a different expression.
              // So, start over, ignoring failures. Ignore failures because we don't require
              // that expressions must not resolve to something that *looks like* an expression but isn't
              return resolveExpressionStringRecursively(resolved.result, true, false);
          } else if (resolved.modified) {
              // Typical case
              return new ModelNode(resolved.result);
          } else if (initial && EXPRESSION_PATTERN.matcher(expressionString).matches()) {
              // We should only get an unmodified expression string back if there was a resolution
              // failure that we ignored.
              assert ignoreDMRResolutionFailure;
              // expressionString came from a node of type expression, so since we did nothing send it back in the same type
              return new ModelNode(new ValueExpression(expressionString));
          } else {
              // The string wasn't really an expression. Two possible cases:
              // 1) if initial == true, someone created a expression node with a non-expression string, which is legal
              // 2) if initial == false, we resolved from an ModelType.EXPRESSION to a string that looked like an
              // expression but can't be resolved. We don't require that expressions must not resolve to something that
              // *looks like* an expression but isn't, so we'll just treat this as a string
              return new ModelNode(expressionString);
          }
      }