public static Expression[] parseExpressions(String template, EvaluationContext context, String expressionPrefix,
         String expressionSuffix) throws ParseException {
      // Prepare an array for results.
      List<Expression> expressions = new ArrayList<>();
      int startIdx = 0;

      while (startIdx < template.length()) {
         int prefixIndex = template.indexOf(expressionPrefix, startIdx);
         if (prefixIndex >= startIdx) {
            // an inner expression was found - this is a composite
            if (prefixIndex > startIdx) {
               log.debug("Found a literal expression starting at {}", startIdx);
               expressions.add(new LiteralExpression(template.substring(startIdx, prefixIndex)));
            }
            int afterPrefixIndex = prefixIndex + expressionPrefix.length();
            int suffixIndex = skipToCorrectEndSuffix(expressionSuffix, template, afterPrefixIndex);
            if (suffixIndex == -1) {
               log.info("No ending suffix '{}' for expression starting at character {}: {}", expressionSuffix,
                     prefixIndex, template.substring(prefixIndex));
               throw new ParseException(template, prefixIndex,
                     "No ending suffix '" + expressionSuffix + "' for expression starting at character " + prefixIndex
                           + ": " + template.substring(prefixIndex));
            }
            if (suffixIndex == afterPrefixIndex) {
               log.info("No expression defined within delimiter '{}' at character {}", expressionPrefix, prefixIndex);
               throw new ParseException(template, prefixIndex, "No expression defined within delimiter '"
                     + expressionPrefix + expressionSuffix + "' at character " + prefixIndex);
            }
            String expr = template.substring(prefixIndex + expressionPrefix.length(), suffixIndex);
            expr = expr.trim();
            if (expr.isEmpty()) {
               log.info("No expression defined within delimiter '{}' at character {}", expressionPrefix, prefixIndex);
               throw new ParseException(template, prefixIndex, "No expression defined within delimiter '"
                     + expressionPrefix + expressionSuffix + "' at character " + prefixIndex);
            }
            expressions.add(doParseExpression(expr, context));
            startIdx = suffixIndex + expressionSuffix.length();
            log.debug("Expression accumulated. Pursuing with index {} on {}", startIdx, template.length());
         } else {
            // no more expression. finalize with a literal.
            expressions.add(new LiteralExpression(template.substring(startIdx, template.length())));
            break;
         }
      }
      return expressions.toArray(new Expression[0]);
   }
@Test
   void testXpathAttributeExpressionWithNestedFunction() {
      String template = "Hello {{ request.body/request/name/@firstname }} it's {{ now() }}";

      // Build a suitable context.
      EvaluationContext context = new EvaluationContext();
      context.registerFunction("now", NowELFunction.class);
      context.setVariable("request", new EvaluableRequest("<request><name firstname=\"Laurent\"/></request>", null));

      Expression[] expressions = ExpressionParser.parseExpressions(template, context, "{{", "}}");

      assertEquals(4, expressions.length);
      assertTrue(expressions[0] instanceof LiteralExpression);
      assertTrue(expressions[1] instanceof VariableReferenceExpression);
      assertTrue(expressions[2] instanceof LiteralExpression);
      assertTrue(expressions[3] instanceof FunctionExpression);

      assertEquals("Laurent", ((VariableReferenceExpression) expressions[1]).getValue(context));
   }