ret = new ValueOfNode(null, ret, select, false);
TemplateNode ret2 = new ValueOfNode(select, false); ret2.next = ret; ret = ret2;
  final TemplateNode parseAttributeValueTemplate(String value, Node source)    throws TransformerConfigurationException, XPathExpressionException  {    current = source;    // Tokenize    int len = value.length();    int off = 0;    List tokens = new ArrayList(); // text tokens    List types = new ArrayList(); // literal or expression    int depth = 0;    for (int i = 0; i < len; i++)      {        char c = value.charAt(i);        if (c == '{')          {            if (i < (len - 1) && value.charAt(i + 1) == '{')              {                tokens.add(value.substring(off, i + 1));                types.add(Boolean.FALSE);                i++;                off = i + 1;                continue;              }            if (depth == 0)              {                if (i - off > 0)                  {                    tokens.add(value.substring(off, i));                    types.add(Boolean.FALSE);                  }                off = i + 1;              }            depth++;          }        else if (c == '}')          {            if (i < (len - 1) && value.charAt(i + 1) == '}')              {                tokens.add(value.substring(off, i + 1));                types.add(Boolean.FALSE);                i++;                off = i + 1;                continue;              }            if (depth == 1)              {                if (i - off > 0)                  {                    tokens.add(value.substring(off, i));                    types.add(Boolean.TRUE);                  }                else                  {                    String msg = "attribute value template " +                      "must contain expression: " + value;                    DOMSourceLocator l = new DOMSourceLocator(source);                    throw new TransformerConfigurationException(msg, l);                  }                off = i + 1;              }            depth--;          }      }    if (depth > 0)      {        String msg = "invalid attribute value template: " + value;        throw new TransformerConfigurationException(msg);      }    if (len - off > 0)      {        // Trailing text        tokens.add(value.substring(off));        types.add(Boolean.FALSE);      }        // Construct template node tree    TemplateNode ret = null;    Document doc = source.getOwnerDocument();    len = tokens.size();    for (int i = len - 1; i >= 0; i--)      {        String token = (String) tokens.get(i);        Boolean type = (Boolean) types.get(i);        if (type == Boolean.TRUE)          {            // Expression text            Expr select = (Expr) xpath.compile(token);            ret = new ValueOfNode(null, ret, select, false);          }        else          {            // Verbatim text            ret = new LiteralNode(null, ret, doc.createTextNode(token));          }      }    return ret;  }