private String substituteVars(String expr) {
    if (expr == null) {
      return null;
    }
    String eval = expr;
    for (int s = 0; s < MAX_SUBST; s++) {
      final int[] varBounds = findSubVariable(eval);
      if (varBounds[SUB_START_IDX] == -1) {
        return eval;
      }
      final String var = eval.substring(varBounds[SUB_START_IDX],
          varBounds[SUB_END_IDX]);
      String val = null;
      try {
        val = System.getProperty(var);
      } catch(SecurityException se) {
        LOG.warn("Unexpected SecurityException in Configuration", se);
      }
      if (val == null) {
        val = getRaw(var);
      }
      if (val == null) {
        return eval; // return literal ${var}: var is unbound
      }
      final int dollar = varBounds[SUB_START_IDX] - "${".length();
      final int afterRightBrace = varBounds[SUB_END_IDX] + "}".length();
      // substitute
      eval = eval.substring(0, dollar)
             + val
             + eval.substring(afterRightBrace);
    }
    throw new IllegalStateException("Variable substitution depth too large: "
                                    + MAX_SUBST + " " + expr);
  }
private String substituteVars ( String expr ) { if ( expr == null ) { return null ; } String eval = expr ; for ( int s = 0 ; s < MAX_SUBST ; s ++ ) { final int [ ] varBounds = findSubVariable ( eval ) ; if ( varBounds [ SUB_START_IDX ] == - 1 ) { return eval ; } final String var = eval . substring ( varBounds [ SUB_START_IDX ] , varBounds [ SUB_END_IDX ] ) ; String val = null ; try { val = System . getProperty ( var ) ; } catch ( SecurityException se ) { LOG . warn ( "Unexpected SecurityException in Configuration" , se ) ; } if ( val == null ) { val = getRaw ( var ) ; } if ( val == null ) { return eval ; } final int dollar = varBounds [ SUB_START_IDX ] - "${" . length ( ) ; final int afterRightBrace = varBounds [ SUB_END_IDX ] + "}" . length ( ) ; eval = eval . substring ( 0 , dollar ) + val + eval . substring ( afterRightBrace ) ; } throw new IllegalStateException ( "Variable substitution depth too large: " + MAX_SUBST + " " + expr ) ; }
Attempts to repeatedly expand the value {@code expr} by replacing the
left-most substring of the form "${var}" in the following precedence order
<ol>
<li>by the value of the Java system property "var" if defined</li>
<li>by the value of the configuration key "var" if defined</li>
</ol>

If var is unbounded the current state of expansion "prefix${var}suffix" is
returned.

@param expr the literal value of a config key
@return null if expr is null, otherwise the value resulting from expanding
expr using the algorithm above.
@throws IllegalArgumentException when more than
{@link Configuration#MAX_SUBST} replacements are required