/**
   * Process text content by including non-expression content verbatim and escaping expression
   * content.
   *
   * @param result the target node where results should be inserted
   * @param textContent the text content being processed
   */
  private void processText(Node result, String textContent) {
    Document ownerDocument = result.getOwnerDocument();

    int start = 0;
    int current = 0;
    while (current < textContent.length()) {
      current = textContent.indexOf("${", current);
      // No expressions, we're done
      if (current < 0) {
        break;
      }

      // An escaped expression "\${"
      if (current > 0 && textContent.charAt(current - 1) == '\\') {
        // Drop the \ by outputting everything before it, and moving past
        // the ${
        if (current - 1 > start) {
          String staticText = textContent.substring(start, current - 1);
          result.appendChild(ownerDocument.createTextNode(staticText));
        }

        start = current;
        current = current + 2;
        continue;
      }

      // Not a real expression, we're done
      int expressionEnd = textContent.indexOf('}', current + 2);
      if (expressionEnd < 0) {
        break;
      }

      // Append the existing static text, if any
      if (current > start) {
        result.appendChild(ownerDocument.createTextNode(textContent.substring(start, current)));
      }

      // Isolate the expression, parse and evaluate
      String expression = textContent.substring(current, expressionEnd + 1);
      String value = evaluate(expression, String.class, "");

      if (!"".equals(value)) {
        // And now escape
        outputBuffer.setLength(0);
        try {
          HtmlSerialization.printEscapedText(value, outputBuffer);
        } catch (IOException e) {
          // Can't happen writing to StringBuilder
          throw new RuntimeException(e);
        }

        result.appendChild(ownerDocument.createTextNode(outputBuffer.toString()));
      }

      // And continue with the next expression
      current = start = expressionEnd + 1;
    }

    // Add any static text left over
    if (start < textContent.length()) {
      result.appendChild(ownerDocument.createTextNode(textContent.substring(start)));
    }
  }