if (pattern == null) { return null; }  Matcher m = VAR_PATTERN.matcher(pattern);  StringBuffer sb = new StringBuffer(); while (m.find()) { String var = m.group(1); String val = (String)variables.get(var); if (val != null) { val = substituteVariables(val, variables); } else { val = m.group(); } m.appendReplacement(sb, val.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$", "\\\\\\$")); } m.appendTail(sb);  return sb.toString();
return substituteVariables(pattern, variables, new Stack());
    public static String substituteVariables(String pattern, Map variables) {    	// if you supply null, null is what you get    	if (pattern == null) {    		return null;    	}    	        Matcher m = VAR_PATTERN.matcher(pattern);                StringBuffer sb = new StringBuffer();        while (m.find()) {            String var = m.group(1);            String val = (String)variables.get(var);            if (val != null) {                val = substituteVariables(val, variables);            } else {                val = m.group();            }            m.appendReplacement(sb, val.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$", "\\\\\\$"));        }        m.appendTail(sb);        return sb.toString();    }