%
    def title = classDoc.name() + (props.docTitle ? " (${props.docTitle})" : "")
    def isVisible = { it.isPublic() || (it.isProtected() && props.protectedScope == 'true') || (!it.isProtected() && !it.isPrivate() && props.packageScope == 'true') || props.privateScope == 'true' }
    def isVisibleExt = { t -> java.lang.reflect.Modifier.isPublic(t.modifiers) || java.lang.reflect.Modifier.isProtected(t.modifiers) }
    def visibleFields = classDoc.fields().findAll(isVisible)
    def visibleProperties = classDoc.properties() // props visible be defn
    def visibleMethods = classDoc.methods().findAll(isVisible)
    def visibleConstructors = classDoc.constructors().findAll(isVisible)
    def visibleNested = classDoc.innerClasses().findAll(isVisible)
    boolean hasFields = !classDoc.isAnnotationType() && visibleFields
    boolean hasProperties = !classDoc.isAnnotationType() && visibleProperties
    boolean hasElements = classDoc.isAnnotationType() && visibleFields
    boolean methodSummaryShown = visibleMethods
    boolean fieldSummaryShown = hasFields
    boolean hasEnumConstants = classDoc.enumConstants().findAll(isVisible)
    def dolink = { t, boolean b ->
        boolean isArray = false
        if (!t || t instanceof String) {
            return classDoc.getDocUrl(t, b)
        }
        if (t instanceof org.codehaus.groovy.tools.groovydoc.ArrayClassDocWrapper) {
            t = t.delegate
            isArray = true
        }
        if (t instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) {
            if (t.fullPathName == 'def') return classDoc.getDocUrl("java.lang.Object def", b)
            return "" + (b ? t.qualifiedTypeName() : t.name()) + "" + (isArray ? "[]" : "")
        }
        return classDoc.getDocUrl(t.qualifiedTypeName(), b) + (isArray ? "[]" : "")
    }
    def linkfull = { t -> dolink(t, true) }
    def linkable = { t -> dolink(t, false) }
    def modifiersWithIgnore = { t, boolean ignorePublic ->
        (t.isPrivate()?"private ":"") +
        (t.isPublic() && !ignorePublic?"public ":"") +
        (t.isProtected()?"protected ":"") +
        (t.isStatic()?"static ":"") +
        (t.isFinal()?"final ":"") +
        (t.respondsTo('isAbstract') && t.isAbstract()?"abstract ":"")
    }
    def modifiers = { t -> modifiersWithIgnore(t, classDoc.isGroovy()) }
    def modifiersBrief = { t ->
        (t.isPrivate()?"private ":"") +
        (t.isProtected()?"protected ":"") +
        (t.isStatic()?"static ":"")
    }
    def annotations = { t, sepChar -> t.annotations() ? t.annotations()*.description().join(sepChar) + sepChar : '' }
    def elementTypes = [
        "required":"true",
        "optional":"false"
    ]
    def isRequired = { f, v -> def req = f.constantValueExpression() == null; req.toString() == v }
    def upcase = { n -> n[0].toUpperCase() + n[1..-1] }
    def paramsOf = { n, boolean brief -> n.parameters().collect{ param -> (brief?'':annotations(param, ' ')) + linkable(param.isTypeAvailable()?param.type():param.typeName()) + (param.vararg()?'... ':' ') + param.name() + (param.defaultValue() ? " = " + param.defaultValue():"") }.join(", ") }
    def nameFromParams = { n -> n.name() + '(' + n.parameters().collect{ param -> param.isTypeAvailable()?param.type().qualifiedTypeName():param.typeName() }.join(', ') + ')' }
    def nameFromJavaParams = { n -> n.name + '(' + n.parameterTypes.collect{ param -> param.name }.join(', ') + ')' }
%>
${title}
<%
def pkg = classDoc.containingPackage().nameWithDots()
if (pkg != "DefaultPackage") {
%>
${pkg}
<% } %>
${classDoc.isGroovy() ? "[Groovy]" : "[Java]"} ${classDoc.typeDescription} ${classDoc.name()}
<%
def parents = classDoc.isInterface() ? classDoc.parentInterfaces : classDoc.parentClasses
if (parents.size() >= 2) {
    %><%
    parents.eachWithIndex { p, i ->
        %>${(i > 0 ? "  " * i + "  " * (i - 1) + " " : "") + ( i == parents.size() - 1 ? p.qualifiedTypeName() : linkfull(p))}\n<%
    }
    %>
" : "") + ( i == parents.size() - 1 ? p.qualifiedTypeName() : linkfull(p))}\n<%
    }
    %><%
}
if (classDoc.isInterface()) {
    Set interfaces = classDoc.parentInterfaces
    interfaces -= classDoc
    if (interfaces) {
        %>- All Superinterfaces: 
- ${interfaces.collect{ linkable(it) }.join(', ')}
<%
    }
} else {
    // TODO follow up the tree collecting interfaces seen?
    def interfaces = classDoc.interfaces()
    if (interfaces) {
        %>- All Implemented Interfaces: 
- ${interfaces.collect{ linkable(it) }.join(', ')}
<%
    }
}
%>
${annotations(classDoc, '\n') + modifiers(classDoc) + classDoc.typeSourceDescription + ' ' + classDoc.name()}
<% if (classDoc.isInterface() && classDoc.interfaces()) {
%>extends ${classDoc.interfaces().collect{ linkable(it) }.join(', ')}
<% } else if (classDoc.superclass()) {
%>extends ${linkable(classDoc.superclass())}
<% } %>
<% if (classDoc.commentText()) { %>
${classDoc.commentText()}
<% } %>
<% if (visibleNested) { %>
    
    
    | Nested Class Summary | 
    <% for (c in visibleNested) { %>
        
        | ${modifiersBrief(c) + c.typeSourceDescription} | ${linkable(c)}
 ${c.firstSentenceCommentText()} | 
    <% } %>
    
     
<% } %>
<% if (hasEnumConstants) { %>
    
    
    | Enum Constant Summary | 
    <% for (ec in classDoc.enumConstants().findAll(isVisible)) { %>
        
        | ${ec.name()}
 ${ec.firstSentenceCommentText()} | 
    <% } %>
    
     
<% } %>
<% if (hasFields) { %>
    
    
    | Field Summary | 
    <% for (field in visibleFields) { %>
        
        | ${modifiersBrief(field) + linkable(field.type())} | ${field.name()}
 ${field.firstSentenceCommentText()} | 
    <% } %>
    
     
<% }
    classes = []
    if (classDoc.isInterface()) {
        classes.addAll(classDoc.interfaces().toList())
    } else {
        if (classDoc.superclass()) classes += classDoc.superclass()
        else classes += new org.codehaus.groovy.tools.groovydoc.ExternalGroovyClassDoc(Object.class)
    }
    visited = [classDoc] as Set
    while (classes) {
        Set nextLevel = []
        classes.each { c ->
            if (c.isInterface()) nextLevel.addAll(c.interfaces().toList())
            else if (c.superclass() && c.qualifiedTypeName() != 'java.lang.Object') nextLevel += c.superclass()
            nextLevel -= visited
            visited += nextLevel
            def list = []
            if (c instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) {
                list = c.fields().findAll(isVisible).collect { field ->
                    "${field.name()}"
                }
            } else {
                list = c.externalClass().fields.findAll{ isVisibleExt(it) }.collect { field ->
                    // "${field.name()}"
                    field.name
                }
            }
            if (list) {
                if (!fieldSummaryShown) {
                    fieldSummaryShown = true
                    %>
                     <%
                }
                %>
                | Fields inherited from ${c.typeSourceDescription} ${linkable(c)} | 
|---|
                | ${list.join(', ')} | 
                
                 <%
            }
        }
        classes = nextLevel
    }
%>
<% if (hasProperties) { %>
    
    
    | Property Summary | 
    <% for (prop in visibleProperties) { %>
        
        | ${modifiersBrief(prop) + linkable(prop.type())} | ${prop.name()}
 ${prop.firstSentenceCommentText()} | 
    <% } %>
    
     
<% } %>
<% if (hasElements) { %>
    <% elementTypes.each { k, v -> %>
        
        <% if (visibleFields.any{ isRequired(it, v) }) {  %>
            
            
            | ${upcase(k)} Element Summary | 
            <% for (element in visibleFields) { %>
                <% if (isRequired(element, v)) { %>
                
                | ${modifiersBrief(element) + linkable(element.type())} | ${element.name()}
 ${element.firstSentenceCommentText()} | 
                <% } %>
            <% } %>
            
        <% } %>
         
    <% } %>
<% } %>
<% if (visibleConstructors) { %>
    
    
    | Constructor Summary | 
    <% for (constructor in visibleConstructors) { %>
        
        | ${modifiersBrief(constructor)}${constructor.name()}(${paramsOf(constructor, true)})
 ${constructor.firstSentenceCommentText()} | 
    <% } %>
    
     
<% } %>
<% if (visibleMethods) { %>
    
    
    | Method Summary | 
    <% for (method in visibleMethods) { %>
        
        | ${modifiersBrief(method)}${linkable(method.returnType())} | ${method.name()}(${paramsOf(method, true)})
 ${method.firstSentenceCommentText()} | 
    <% } %>
    
     
<% }
    Set classes = []
    if (classDoc.isInterface()) {
        classes.addAll(classDoc.interfaces().toList())
    } else {
        if (classDoc.superclass()) classes += classDoc.superclass()
        else classes += new org.codehaus.groovy.tools.groovydoc.ExternalGroovyClassDoc(Object.class)
    }
    Set visited = [classDoc] as Set
    while (classes) {
        Set nextLevel = []
        classes.each { c ->
            if (c.isInterface()) nextLevel.addAll(c.interfaces().toList())
            else if (c.superclass() && c.qualifiedTypeName() != 'java.lang.Object') nextLevel += c.superclass()
            nextLevel -= visited
            visited += nextLevel
            def list = []
            if (c instanceof org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc) {
                list = c.methods().findAll(isVisible).collect { method ->
                    "${method.name()}"
                }
            } else {
                list = c.externalClass().methods.findAll{ isVisibleExt(it) }.collect { method ->
                    linkable(c.externalClass().name + "#" + nameFromJavaParams(method) + " " + method.name)
                }
            }
            if (list) {
                if (!methodSummaryShown) {
                    methodSummaryShown = true
                    %>
                     <%
                }
                %>
                | Methods inherited from ${c.typeSourceDescription} ${linkable(c)} | 
|---|
                | ${list.join(', ')} | 
                
                 <%
            }
        }
        classes = nextLevel
    }
%>
<% if (hasEnumConstants) { %>
    
    <% for (ec in classDoc.enumConstants()) { %>
        ${ec.name()}
        ${modifiers(ec) + '' + classDoc.name() + ''} ${ec.name()}
        
        - ${ec.commentText()}
        
        
    <% } %>
     
<% } %>
<% if (hasFields) { %>
    
    <% for (field in visibleFields) { %>
        ${field.name()}
        ${annotations(field, '\n') + modifiersWithIgnore(field, false) + linkable(field.type())} ${field.name()}
        
        - ${field.commentText()}
        
        
    <% } %>
     
<% } %>
<% if (hasProperties) { %>
    
    <% for (prop in visibleProperties) { %>
        ${prop.name()}
        ${annotations(prop, '\n') + modifiers(prop) + linkable(prop.type())} ${prop.name()}
        
        - ${prop.commentText()}
        
        
    <% } %>
     
<% } %>
<% if (hasElements) { %>
    
    <% for (element in visibleFields) { %>
        ${element.name()}
        ${modifiers(element) + linkable(element.type())} ${element.name()}
        
        - ${element.commentText()}
        
        
    <% } %>
     
<% } %>
<% if (visibleConstructors) { %>
    
    <% for (constructor in visibleConstructors) { %>
        
        ${constructor.name()}
        ${annotations(constructor, '\n') + modifiers(constructor)}${constructor.name()}(${paramsOf(constructor, false)})
        
        - ${constructor.commentText()}
        
        
    <% } %>
     
<% } %>
<% if (visibleMethods) { %>
    
    <% for (method in visibleMethods) { %>
        
        ${method.name()}
        ${annotations(method, '\n') + modifiers(method)}${linkable(method.returnType())} ${method.name()}(${paramsOf(method, false)})
        
        - ${method.commentText()}
        
        
    <% } %>
     
<% } %>
${props['footer']?:""}