private void writeCoverage(OutputStream out) throws IOException {

    out.write("<h3 id=\"coverageDetail\">Coverage Detail</h3>\n".getBytes());

    StringBuilder key = new StringBuilder();
    key.append("<table>");
    key.append("<tr><th style=\"background-color:#dddddd\">Colour Key</th></tr>");
    key.append(
        "<tr><td style=\"background-color:"
            + COLOUR_SHADE_GREEN
            + ";text-align:center\">Assertion is covered</td></tr>");
    key.append(
        "<tr><td style=\"background-color:"
            + COLOUR_SHADE_RED
            + ";text-align:center\">Assertion is not covered</td></tr>");
    key.append(
        "<tr><td style=\"background-color:"
            + COLOUR_SHADE_ORANGE
            + ";text-align:center\">Assertion test is unimplemented</td></tr>");
    key.append(
        "<tr><td style=\"background-color:"
            + COLOUR_SHADE_BLUE
            + ";text-align:center\">Assertion is untestable</td></tr>");
    key.append("</table>");
    out.write(key.toString().getBytes());

    for (String sectionId : auditParser.getSectionIds()) {

      List<AuditAssertion> sectionAssertions = auditParser.getAssertionsForSection(sectionId);

      if (sectionAssertions != null && !sectionAssertions.isEmpty()) {
        StringBuilder sb = new StringBuilder();

        out.write(
            ("<h4 class=\"sectionHeader\" id=\""
                    + sectionId
                    + "\">Section "
                    + sectionId
                    + " - "
                    + escape(auditParser.getSectionTitle(sectionId))
                    + "</h4>\n")
                .getBytes());

        for (AuditAssertion assertion : sectionAssertions) {
          List<SpecReference> coverage = getCoverageForAssertion(sectionId, assertion.getId());
          TestStatus status = getStatus(coverage);

          String divClass = null;

          if (assertion.isTestable()) {
            if (status.equals(TestStatus.UNCOVERED)) {
              divClass = "fail";
            } else if (status.equals(TestStatus.UNIMPLEMENTED)) {
              divClass = "skip";
            } else {
              divClass = "pass";
            }
          } else {
            divClass = "untestable";
          }

          sb.append("  <div class=\"" + divClass + "\">\n");

          if (assertion.isImplied()) {
            sb.append(
                "<span class=\"implied\">The following assertion is not made explicitly by the spec, however it is implied</span>");
          }

          sb.append("    <span class=\"code\">");
          sb.append(assertion.getId());
          sb.append(")");

          if (!Strings.isEmpty(assertion.getNote())) {
            sb.append(
                "<img title=\""
                    + assertion.getNote()
                    + "\" src=\"images/blank.png\" class=\"stickynote\"/>");
            // sb.append("<a title=\"" + assertion.getNote() + "\"><img title=\"" +
            // assertion.getNote() + "\" src=\"images/blank.png\" class=\"stickynote\"/></a>");
          }

          sb.append("</span>\n");

          sb.append("    <div class=\"results\">");

          sb.append("<p class=\"description\">");
          String imageFilename = sectionId + "." + assertion.getId() + ".png";
          File imageFile = new File(imageSrcDir, imageFilename);

          if (imageFile.exists()) {
            sb.append("<img src=\"images/" + imageFile.getName() + "\" class=\"embeddedImage\"/>");
            copyFile(imageFile, new File(imageTargetDir, imageFilename));
          }

          String assertionText =
              parseStrikethrough(parseBold(parseLiteral(escape(assertion.getText()))));
          sb.append(assertionText);
          sb.append("</p>\n");

          if (assertion.isTestable()) {
            sb.append("    <div class=\"coverage\">\n");
            sb.append("      <p class=\"coverageHeader\">Coverage</p>\n");

            String currentPackageName = null;

            if (status.equals(TestStatus.UNCOVERED)) {
              sb.append("        <p class=\"noCoverage\">No tests exist for this assertion</p>\n");
            } else {
              for (SpecReference ref : coverage) {
                if (!ref.getPackageName().equals(currentPackageName)) {
                  currentPackageName = ref.getPackageName();
                  sb.append("        <div class=\"packageName\">");
                  sb.append(currentPackageName);
                  sb.append("        </div>\n");
                }

                sb.append("        <div class=\"coverageMethod\">");
                sb.append(ref.getClassName());
                sb.append(".");
                sb.append(ref.getMethodName());
                sb.append("()");

                if (fisheyeBaseUrl != null) {
                  sb.append("<a class=\"external\" target=\"_blank\" href=\"");
                  sb.append(fisheyeBaseUrl);
                  sb.append(currentPackageName.replace('.', '/'));
                  sb.append("/");
                  sb.append(ref.getClassName());
                  sb.append(".java");
                  sb.append("\">fisheye</a>");
                }

                if (svnBaseUrl != null) {
                  if (fisheyeBaseUrl != null) {
                    sb.append("|");
                  }

                  sb.append("<a class=\"external\" target=\"_blank\" href=\"");
                  sb.append(svnBaseUrl);
                  sb.append(currentPackageName.replace('.', '/'));
                  sb.append("/");
                  sb.append(ref.getClassName());
                  sb.append(".java");
                  sb.append("\">svn</a>");
                }

                sb.append("</div>\n");
              }
            }

            sb.append("    </div>\n");
          } else if (!coverage.isEmpty()) {
            sb.append("<b>A test exists for this untestable assertion!</b>");
          }

          sb.append("</div></div>");
        }

        out.write(sb.toString().getBytes());
      } else {
        // We still want to be able to jump to this section by clicking on the links
        // in the chapter and section summaries
        out.write(
            ("<div style=\"visibility:hidden\" id=\"" + sectionId + "\"></div>\n").getBytes());
      }
    }
  }
  private void writeSectionSummary(OutputStream out) throws IOException {
    StringBuilder sb = new StringBuilder();

    sb.append("<h3 id=\"sectionSummary\">Section Summary</h3>\n");

    sb.append("<table width=\"100%\">");

    sb.append("<tr style=\"background-color:#dddddd\">");
    sb.append("<th align=\"left\">Section</th>");
    sb.append("<th>Assertions</th>");
    sb.append("<th>Testable</th>");
    sb.append("<th>Total Tested</th>");
    sb.append("<th>Tested<br /> (unimplemented)</th>");
    sb.append("<th>Tested<br /> (implemented)</th>");
    sb.append("<th>Coverage %</th>");
    sb.append("</tr>");

    boolean odd = true;

    for (String sectionId : auditParser.getSectionIds()) {

      if (odd) {
        sb.append("<tr style=\"background-color:#f7f7f7\">");
      } else {
        sb.append("<tr>");
      }

      odd = !odd;

      int margin = (sectionId.split("[.]").length - 1) * 16;

      sb.append("<td style=\"padding-left:" + margin + "px\">");
      sb.append("<a href=\"#" + sectionId + "\">");
      sb.append(sectionId);
      sb.append(" ");
      sb.append(auditParser.getSectionTitle(sectionId));
      sb.append("</a>");
      sb.append("</td>");

      int assertions = auditParser.getAssertionsForSection(sectionId).size();
      int testable = 0;
      int implemented = 0;
      int unimplemented = 0;

      for (AuditAssertion assertion : auditParser.getAssertionsForSection(sectionId)) {
        if (assertion.isTestable()) testable++;

        TestStatus status = getStatus(getCoverageForAssertion(sectionId, assertion.getId()));
        if (status.equals(TestStatus.COVERED)) {
          implemented++;
        } else if (status.equals(TestStatus.UNIMPLEMENTED)) {
          unimplemented++;
        }
      }

      int tested = implemented + unimplemented;

      double coveragePercent = testable > 0 ? ((implemented * 1.0) / testable) * 100 : -1;

      sb.append("<td align=\"center\">");
      sb.append(assertions);
      sb.append("</td>");

      sb.append("<td align=\"center\">");
      sb.append(testable);
      sb.append("</td>");

      sb.append("<td align=\"center\">");
      sb.append(tested);
      sb.append("</td>");

      sb.append("<td align=\"center\">");
      sb.append(unimplemented);
      sb.append("</td>");

      sb.append("<td align=\"center\">");
      sb.append(implemented);
      sb.append("</td>");

      if (coveragePercent >= 0) {
        String bgColor =
            coveragePercent < failThreshold
                ? "#ffaaaa"
                : coveragePercent < passThreshold
                    ? "#ffffaa"
                    : coveragePercent > 100 ? "#FF00CC" : "#aaffaa";

        sb.append("<td align=\"center\" style=\"background-color:" + bgColor + "\">");
        sb.append(String.format("%.2f%%", coveragePercent));
        sb.append("</td>");
      } else {
        sb.append("<td />");
      }

      sb.append("</tr>");
    }

    sb.append("</table>");
    out.write(sb.toString().getBytes());
  }