public static String resolvePlaceholders(String pattern,
                                             String placeholderNamespace,
                                             Map<String, Object> variableValues) {
        StringBuilder sb = new StringBuilder(pattern);
        String placeholderPrefix = "$" + placeholderNamespace + "{";
        int endIndex;
        int startIndex = sb.indexOf(placeholderPrefix);

        while (startIndex > -1) {
            endIndex = sb.indexOf("}", startIndex);
            if (endIndex == -1) {
                // ignore bad syntax, search finished
                break;
            }

            String variableName = sb.substring(startIndex + placeholderPrefix.length(), endIndex);
            Object variableValue = variableValues.get(variableName);
            // ignore missing values
            if (variableValue != null) {
                String valueStr = variableValue.toString();
                sb.replace(startIndex, endIndex + 1, valueStr);
                endIndex = startIndex + valueStr.length();
            }

            startIndex = sb.indexOf(placeholderPrefix, endIndex);
        }
        return sb.toString();
    }
@Test
    void testResolvePlaceholders() {
        assertResolvePlaceholder(
                "noPlaceholders",
                "noPlaceholders",
                "", "param", "value");
        assertResolvePlaceholder(
                "param: value",
                "param: ${param}",
                "", "param", "value");
        assertResolvePlaceholder(
                "param: ${param",
                "param: ${param",
                "", "param", "value");
        assertResolvePlaceholder(
                "missing: ${missing}",
                "missing: ${missing}",
                "", "param", "value");
        assertResolvePlaceholder(
                "missing: ${missing}, param: value",
                "missing: ${missing}, param: ${param}",
                "", "param", "value");
        assertResolvePlaceholder(
                "broken: ${broken, param: ${param}",
                "broken: ${broken, param: ${param}",
                "", "param", "value");
        assertResolvePlaceholder(
                "param: value, broken: ${broken",
                "param: ${param}, broken: ${broken",
                "", "param", "value");
        assertResolvePlaceholder(
                "missing: ${missing}, param: value, broken: ${broken",
                "missing: ${missing}, param: ${param}, broken: ${broken",
                "", "param", "value");
        assertResolvePlaceholder(
                "param1: value1, param2: value2, param3: value3",
                "param1: ${param1}, param2: ${param2}, param3: ${param3}",
                "", "param1", "value1", "param2", "value2", "param3", "value3");
        assertResolvePlaceholder(
                "param: value, param: $OTHER_PREFIX{param}",
                "param: $PREFIX{param}, param: $OTHER_PREFIX{param}",
                "PREFIX", "param", "value");
    }