private String getStringToSign(MessageContext msgCtxt) throws Exception {
    String msg = (String) this.properties.get("string-to-sign");
    if (msg == null || msg.equals("")) {
      // by default, get the content of the message (either request or response)
      return msgCtxt.getVariable("message.content");
    }

    // replace ALL curly-braced items in the string-to-sign
    TemplateString ts = new TemplateString(msg);
    Map valuesMap = new HashMap();
    for (String s : ts.variableNames) {
      valuesMap.put(s, msgCtxt.getVariable(s));
    }
    StrSubstitutor sub = new StrSubstitutor(valuesMap);
    String resolvedString = sub.replace(ts.template);
    return resolvedString;
  }
 // If the value of a property value begins and ends with curlies,
 // and contains no spaces, eg, {apiproxy.name}, then "resolve" the
 // value by de-referencing the context variable whose name appears
 // between the curlies.
 private String resolvePropertyValue(String spec, MessageContext msgCtxt) {
   if (spec.startsWith("{") && spec.endsWith("}") && (spec.indexOf(" ") == -1)) {
     String varname = spec.substring(1, spec.length() - 1);
     String value = msgCtxt.getVariable(varname);
     return value;
   }
   return spec;
 }