public void renderTo(ClassDoc classDoc, Element parent) {
    Document document = parent.getOwnerDocument();

    Element title = document.createElement("title");
    parent.appendChild(title);
    title.appendChild(document.createTextNode(classDoc.getSimpleName()));

    Element list = document.createElement("segmentedlist");
    parent.appendChild(list);
    Element segtitle = document.createElement("segtitle");
    list.appendChild(segtitle);
    segtitle.appendChild(document.createTextNode("API Documentation"));
    Element listItem = document.createElement("seglistitem");
    list.appendChild(listItem);
    Element seg = document.createElement("seg");
    listItem.appendChild(seg);
    Element apilink = document.createElement("apilink");
    seg.appendChild(apilink);
    apilink.setAttribute("class", classDoc.getName());
    apilink.setAttribute("style", classDoc.getStyle());

    warningsRenderer.renderTo(classDoc, "class", parent);

    for (Element element : classDoc.getComment()) {
      parent.appendChild(document.importNode(element, true));
    }
    NodeList otherContent = classDoc.getClassSection().getChildNodes();
    for (int i = 0; i < otherContent.getLength(); i++) {
      Node child = otherContent.item(i);
      if (child instanceof Element && !((Element) child).getTagName().equals("section")) {
        parent.appendChild(document.importNode(child, true));
      }
    }
  }
  /** Builds the properties of the given class */
  void build(ClassDoc classDoc) {
    Element thead = getChild(classDoc.getPropertiesTable(), "thead");
    Element tr = getChild(thead, "tr");
    List<Element> header = children(tr, "td");
    if (header.size() < 1) {
      throw new RuntimeException(
          String.format("Expected at least 1 <td> in <thead>/<tr>, found: %s", header));
    }
    Map<String, Element> inheritedValueTitleMapping = new HashMap<String, Element>();
    List<Element> valueTitles = new ArrayList<Element>();
    for (int i = 1; i < header.size(); i++) {
      Element element = header.get(i);
      Element override = findChild(element, "overrides");
      if (override != null) {
        element.removeChild(override);
        inheritedValueTitleMapping.put(override.getTextContent(), element);
      }
      Node firstChild = element.getFirstChild();
      if (firstChild instanceof Text) {
        firstChild.setTextContent(firstChild.getTextContent().replaceFirst("^\\s+", ""));
      }
      Node lastChild = element.getLastChild();
      if (lastChild instanceof Text) {
        lastChild.setTextContent(lastChild.getTextContent().replaceFirst("\\s+$", ""));
      }
      valueTitles.add(element);
    }

    ClassDoc superClass = classDoc.getSuperClass();

    // adding the properties from the super class onto the inheriting class
    Map<String, PropertyDoc> props = new TreeMap<String, PropertyDoc>();
    if (superClass != null) {
      for (PropertyDoc propertyDoc : superClass.getClassProperties()) {
        Map<String, ExtraAttributeDoc> additionalValues =
            new LinkedHashMap<String, ExtraAttributeDoc>();
        for (ExtraAttributeDoc attributeDoc : propertyDoc.getAdditionalValues()) {
          String key = attributeDoc.getKey();
          if (inheritedValueTitleMapping.get(key) != null) {
            ExtraAttributeDoc newAttribute =
                new ExtraAttributeDoc(
                    inheritedValueTitleMapping.get(key), attributeDoc.getValueCell());
            additionalValues.put(newAttribute.getKey(), newAttribute);
          } else {
            additionalValues.put(key, attributeDoc);
          }
        }

        props.put(propertyDoc.getName(), propertyDoc.forClass(classDoc, additionalValues.values()));
      }
    }

    for (Element row : children(classDoc.getPropertiesTable(), "tr")) {
      List<Element> cells = children(row, "td");
      if (cells.size() != header.size()) {
        throw new RuntimeException(
            String.format("Expected %s <td> elements in <tr>, found: %s", header.size(), tr));
      }
      String propName = cells.get(0).getTextContent().trim();
      PropertyMetaData property = classDoc.getClassMetaData().findProperty(propName);
      if (property == null) {
        throw new RuntimeException(
            String.format(
                "No metadata for property '%s.%s'. Available properties: %s",
                classDoc.getName(), propName, classDoc.getClassMetaData().getPropertyNames()));
      }

      Map<String, ExtraAttributeDoc> additionalValues =
          new LinkedHashMap<String, ExtraAttributeDoc>();

      if (superClass != null) {
        PropertyDoc overriddenProp = props.get(propName);
        if (overriddenProp != null) {
          for (ExtraAttributeDoc attributeDoc : overriddenProp.getAdditionalValues()) {
            additionalValues.put(attributeDoc.getKey(), attributeDoc);
          }
        }
      }

      for (int i = 1; i < header.size(); i++) {
        if (cells.get(i).getFirstChild() == null) {
          continue;
        }
        ExtraAttributeDoc attributeDoc =
            new ExtraAttributeDoc(valueTitles.get(i - 1), cells.get(i));
        additionalValues.put(attributeDoc.getKey(), attributeDoc);
      }
      PropertyDoc propertyDoc =
          new PropertyDoc(
              property,
              javadocConverter.parse(property, listener).getDocbook(),
              new ArrayList<ExtraAttributeDoc>(additionalValues.values()));
      if (propertyDoc.getDescription() == null) {
        throw new RuntimeException(
            String.format(
                "Docbook content for '%s.%s' does not contain a description paragraph.",
                classDoc.getName(), propName));
      }

      props.put(propName, propertyDoc);
    }

    for (PropertyDoc propertyDoc : props.values()) {
      classDoc.addClassProperty(propertyDoc);
    }
  }