class StandardUtextTagProcessor extends AbstractAttributeTagProcessor {

    public static final int PRECEDENCE = 1400;
    public static final String ATTR_NAME = "utext";


    public StandardUtextTagProcessor(final TemplateMode templateMode, final String dialectPrefix) {
        super(templateMode, dialectPrefix, null, false, ATTR_NAME, true, PRECEDENCE, true);
    }


    @Override
    protected void doProcess(
            final ITemplateContext context,
            final IProcessableElementTag tag,
            final AttributeName attributeName,
            final String attributeValue,
            final IElementTagStructureHandler structureHandler) {<FILL_FUNCTION_BODY>}


    /*
     * This method will be used for determining if we actually need to apply a parser to the unescaped text that we
     * are going to use a a result of this th:utext execution. If there is no '>' character in it, then it is
     * nothing but a piece of text, and applying the parser would be overkill
     */
    private static boolean mightContainStructures(final CharSequence unescapedText) {
        int n = unescapedText.length();
        char c;
        while (n-- != 0) {
            c = unescapedText.charAt(n);
            if (c == '>' || c == ']') {
                // Might be the end of a structure!
                return true;
            }
        }
        return false;
    }


}


        final IEngineConfiguration configuration = context.getConfiguration();

        final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);

        final IStandardExpression expression = expressionParser.parseExpression(context, attributeValue);

        final Object expressionResult;
        if (expression != null && expression instanceof FragmentExpression) {
            // This is merely a FragmentExpression (not complex, not combined with anything), so we can apply a shortcut
            // so that we don't require a "null" result for this expression if the template does not exist. That will
            // save a call to resource.exists() which might be costly.

            final FragmentExpression.ExecutedFragmentExpression executedFragmentExpression =
                    FragmentExpression.createExecutedFragmentExpression(context, (FragmentExpression) expression);

            expressionResult =
                    FragmentExpression.resolveExecutedFragmentExpression(context, executedFragmentExpression, true);

        } else {

            expressionResult = expression.execute(context, StandardExpressionExecutionContext.RESTRICTED);

        }


        // If result is no-op, there's nothing to execute
        if (expressionResult == NoOpToken.VALUE) {
            return;
        }


        /*
         * First of all we should check whether the expression result is a Fragment so that, in such case, we can
         * avoid creating a String in memory for it and just append its model.
         */
        if (expressionResult != null && expressionResult instanceof Fragment) {
            if (expressionResult == Fragment.EMPTY_FRAGMENT) {
                structureHandler.removeBody();
                return;
            }
            structureHandler.setBody(((Fragment)expressionResult).getTemplateModel(), false);
            return;
        }


        final String unescapedTextStr = (expressionResult == null ? "" : expressionResult.toString());

        /*
         * We will check if there are configured post processors or not. The reason we do this is because output
         * inserted as a result of a th:utext attribute, even if it might be markup, will never be considered as
         * 'processable', i.e. no other processors/inliner will ever be able to act on it. The main reason for this
         * is to protect against code injection.
         *
         * So the only other agents that would be able to modify these th:utext results are POST-PROCESSORS. And
         * they will indeed need markup to have been parsed in order to separate text from structures, so that's why
         * we check if there actually are any post-processors and, if not (most common case), simply output the
         * expression result as if it were a mere (unescaped) text node.
         */
        final Set<IPostProcessor> postProcessors = configuration.getPostProcessors(getTemplateMode());
        if (postProcessors.isEmpty()) {
            structureHandler.setBody(unescapedTextStr, false);
            return;
        }


        /*
         * We have post-processors, so from here one we will have to decide whether we need to parse the unescaped
         * text or not...
         */
        if (!mightContainStructures(unescapedTextStr)) {
            // If this text contains no markup structures, there would be no need to parse it or treat it as markup!
            structureHandler.setBody(unescapedTextStr, false);
            return;
        }


        /*
         * We have post-processors AND this text might contain structures, so there is no alternative but parsing
         */
        final TemplateModel parsedFragment =
                configuration.getTemplateManager().parseString(
                        context.getTemplateData(),
                        unescapedTextStr,
                        0, 0, // we won't apply offset here because the inserted text does not really come from the template itself
                        null, // No template mode forcing required
                        false); // useCache == false because we could potentially pollute the cache with too many entries (th:utext is too variable!)

        // Setting 'processable' to false avoiding text inliners processing already generated text,
        // which in turn avoids code injection.
        structureHandler.setBody(parsedFragment, false);


    
<methods><variables>private final non-sealed boolean removeAttribute