protected int encodeHeader(MessageTree tree, ChannelBuffer buf, Ruler ruler) {
    BufferHelper helper = m_bufferHelper;
    XmlBuilder b = new XmlBuilder();
    StringBuilder sb = b.getResult();

    sb.append("<tr class=\"header\"><td>");
    sb.append(VERSION).append(" ").append(tree.getDomain()).append(" ");
    sb.append(tree.getHostName()).append(" ").append(tree.getIpAddress()).append(" ");
    sb.append(tree.getThreadGroupName()).append(" ").append(tree.getThreadId()).append(" ");
    sb.append(tree.getThreadName()).append(" ").append(tree.getMessageId()).append(" ");
    sb.append(tree.getParentMessageId()).append(" ").append(tree.getRootMessageId()).append(" ");
    sb.append(tree.getSessionToken()).append(" ");
    sb.append("</td></tr>");
    sb.append("<tr><td>");

    int height = ruler.getHeight();
    int width = ruler.getWidth();

    b.add(
        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\r\n");
    b.tag1(
        "svg",
        "x",
        0,
        "y",
        0,
        "width",
        width,
        "height",
        height,
        "viewBox",
        "0,0," + width + "," + height,
        "xmlns",
        "http://www.w3.org/2000/svg",
        "version",
        "1.1");
    b.tag1("g", "font-size", "12", "stroke", "gray");

    return helper.write(buf, sb.toString());
  }
  protected int encodeRuler(ChannelBuffer buf, Locator locator, Ruler ruler) {
    BufferHelper helper = m_bufferHelper;
    XmlBuilder b = new XmlBuilder();
    StringBuilder sb = b.getResult();
    PathBuilder p = new PathBuilder();
    int height = ruler.getHeight();

    b.tag1(
        "g",
        "id",
        "ruler",
        "font-size",
        "12",
        "text-anchor",
        "middle",
        "stroke",
        "black",
        "stroke-width",
        "1");

    int unitNum = ruler.getUnitNum();
    int unitStep = ruler.getUnitStep();
    int unit = (int) ruler.getUnit();
    int x = ruler.getOffsetX();
    int y = 10;

    for (int i = 0; i <= unitNum; i++) {
      String text;

      if (unitStep >= 1000) {
        text = (i * unitStep / 1000) + "ms";
      } else {
        text = (i * unitStep) + "us";
      }

      b.tagWithText("text", text, "x", x + i * unit, "y", y, "stroke-width", "0");
    }

    for (int i = 0; i <= unitNum; i++) {
      b.tag(
          "path", "d", p.moveTo(x + i * unit, y + 6).v(height).build(), "stroke-dasharray", "3,4");
    }

    b.tag2("g");

    return helper.write(buf, sb.toString());
  }
  protected int encodeTransactionLine(
      MessageTree tree, Transaction t, ChannelBuffer buf, Locator locator, Ruler ruler) {
    BufferHelper helper = m_bufferHelper;
    XmlBuilder b = new XmlBuilder();
    int width = 6;
    int height = 18;
    int x = 0;
    int y = locator.getLine() * height + ruler.getOffsetY();
    String tid = "t" + locator.getLine();
    long t0 = tree.getMessage().getTimestamp();
    long t1 = t.getTimestamp();
    int rx = ruler.calcX((t1 - t0) * 1000);
    int rw = ruler.calcWidth(t.getDurationInMicros() * 1000);
    int[] segments = getTransactionDurationSegments(t);

    b.branch(locator, x, y, width, height);
    x += locator.getLevel() * width;

    if (t.getStatus().equals("0")) {
      b.tag1("text", "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0");
    } else {
      b.tag1("text", "x", x, "y", y - 5, "font-weight", "bold", "stroke-width", "0", "fill", "red");
    }

    b.add(t.getType()).newLine();
    b.tag(
        "set",
        "attributeName",
        "fill",
        "to",
        "red",
        "begin",
        tid + ".mouseover",
        "end",
        tid + ".mouseout");
    b.tag2("text");

    if (segments == null) {
      String durationInMillis =
          String.format("%.2f %s", t.getDurationInMicros() / 1000.0, t.getName());

      b.tag(
          "rect",
          "x",
          rx + 1,
          "y",
          y - 15,
          "width",
          rw,
          "height",
          height - 2,
          "fill",
          "#0066ff",
          "opacity",
          "0.5");
      b.tagWithText(
          "text",
          durationInMillis,
          "x",
          rx + 5,
          "y",
          y - 3,
          "font-size",
          "11",
          "stroke-width",
          "0");
    } else {
      int index = 0;

      for (int segment : segments) {
        int w = ruler.calcWidth(segment);
        String durationInMillis =
            String.format("%.2f %s", segment / 1000.0 / 1000.0, index == 0 ? t.getName() : "");
        String color = m_colors[index % m_colors.length];

        b.tag(
            "rect",
            "x",
            rx + 1,
            "y",
            y - 15,
            "width",
            w,
            "height",
            height - 2,
            "fill",
            color,
            "opacity",
            "0.5");
        b.tagWithText(
            "text",
            durationInMillis,
            "x",
            rx + 5,
            "y",
            y - 3,
            "font-size",
            "11",
            "stroke-width",
            "0");

        index++;
        rx += w;
      }
    }

    b.tag(
        "rect",
        "id",
        tid,
        "x",
        ruler.getOffsetX() + 1,
        "y",
        y - 15,
        "width",
        ruler.getWidth(),
        "height",
        height,
        "fill",
        "#ffffff",
        "stroke-width",
        "0",
        "opacity",
        "0.01");

    return helper.write(buf, b.getResult().toString());
  }