code: public static String resolve( Properties props, String value )
      {
          if( value == null )
          {
              return null;
          }
  
          // optimization for common case.
          if( value.indexOf( '$' ) < 0 )
          {
              return value;
          }
          int pos1 = value.indexOf( "${" );
          if( pos1 < 0 )
          {
              return value;
          }
  
          Stack<String> stack = new Stack<String>();
          StringTokenizer st = new StringTokenizer( value, "${}", true );
  
          while( st.hasMoreTokens() )
          {
              String token = st.nextToken();
              processToken( token, stack, props );
          }
          String result = "";
          while( stack.size() > 0 )
          {
              result = stack.pop() + result;
          }
          return result;
      }
docs: Symbol substitution from properties.
  Replace any occurances of ${[key]} with the value of the property
  assigned to the [key] in the supplied properties argument.
  
  @param props the source properties from which substitution is resolved
  @param value a string containing possibly multiple ${[value]} sequences
  
  @return the expanded string