Generate signatures in output format
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt
index 6537465..6dccb06 100644
--- a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt
+++ b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt
@@ -79,6 +79,7 @@
         val languageService: LanguageService,
         val uriProvider: JavaLayoutHtmlUriProvider,
         val templateService: JavaLayoutHtmlTemplateService,
+        val logger: DokkaLogger,
         val uri: URI
 ) {
 
@@ -151,7 +152,7 @@
 
     private fun FlowContent.fullFunctionDocs(node: DocumentationNode) {
         div {
-            id = node.signature()
+            id = node.signatureForAnchor(logger)
             h3 { +node.name }
             pre { renderedSignature(node, FULL) }
             metaMarkup(node.content)
@@ -362,7 +363,7 @@
     var outlineFactoryService: JavaLayoutHtmlFormatOutlineFactoryService? = null
 
     fun createOutputBuilderForNode(node: DocumentationNode, output: Appendable)
-            = JavaLayoutHtmlFormatOutputBuilder(output, languageService, this, templateService, mainUri(node))
+            = JavaLayoutHtmlFormatOutputBuilder(output, languageService, this, templateService, logger, mainUri(node))
 
     override fun tryGetContainerUri(node: DocumentationNode): URI? {
         return when (node.kind) {
@@ -378,12 +379,14 @@
             NodeKind.Package -> tryGetContainerUri(node)?.resolve("package-summary.html")
             in classLike -> tryGetContainerUri(node)?.resolve("#")
             in memberLike -> tryGetMainUri(node.owner!!)?.resolveInPage(node)
-            NodeKind.TypeParameter -> node.path.firstNotNullResult(this::tryGetContainerUri)?.also { logger.warn("Not implemented mainUri for $node") }
+            NodeKind.TypeParameter -> node.path.asReversed().drop(1).firstNotNullResult(this::tryGetMainUri)?.resolveInPage(node)
             NodeKind.AllTypes -> tryGetContainerUri(node.owner!!)?.resolve("allclasses.html")
             else -> null
         }
     }
 
+    fun URI.resolveInPage(node: DocumentationNode): URI = resolve("#${node.signatureUrlEncoded(logger)}")
+
     fun buildClass(node: DocumentationNode, parentDir: File) {
         val fileForClass = parentDir.resolve(node.simpleName() + ".html")
         fileForClass.bufferedWriter().use {
@@ -438,8 +441,23 @@
     }
 }
 
-fun DocumentationNode.signature() = detail(NodeKind.Signature).name
-fun DocumentationNode.signatureUrlEncoded() = URLEncoder.encode(detail(NodeKind.Signature).name, "UTF-8")
+fun DocumentationNode.signatureForAnchor(logger: DokkaLogger): String = when (kind) {
+    NodeKind.Function -> buildString {
+        detailOrNull(NodeKind.Receiver)?.let {
+            append("(")
+            append(it.detail(NodeKind.Type).qualifiedNameFromType())
+            append(").")
+        }
+        append(name)
+        details(NodeKind.Parameter).joinTo(this, prefix = "(", postfix = ")") { it.detail(NodeKind.Type).qualifiedNameFromType() }
+    }
+    NodeKind.Property ->
+        "$name:${detail(NodeKind.Type).qualifiedNameFromType()}"
+    NodeKind.TypeParameter, NodeKind.Parameter -> owner!!.signatureForAnchor(logger) + "/" + name
+    else -> "Not implemented signatureForAnchor $this".also { logger.warn(it) }
+}
+
+fun DocumentationNode.signatureUrlEncoded(logger: DokkaLogger) = URLEncoder.encode(signatureForAnchor(logger), "UTF-8")
 
 
 fun URI.relativeTo(uri: URI): URI {
@@ -471,6 +489,4 @@
             append(it)
         }
     })
-}
-
-fun URI.resolveInPage(node: DocumentationNode): URI = resolve("#${node.signatureUrlEncoded()}")
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
index 61bf50d..dd29cfc 100644
--- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
+++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
@@ -232,6 +232,7 @@
             val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor)
             if (externalLink != null) {
                 node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
+                node.append(DocumentationNode(classifierDescriptor.fqNameUnsafe.asString(), Content.Empty, NodeKind.QualifiedName), RefKind.Detail)
             } else {
                 link(node, classifierDescriptor,
                         if (classifierDescriptor.isBoringBuiltinClass()) RefKind.HiddenLink else RefKind.Link)
diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
index f33c8c9..6f8ff44 100644
--- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
+++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
@@ -47,8 +47,7 @@
             val typeParameter = functionWithTypeParameter.details(NodeKind.TypeParameter).first()
             if (functionWithTypeParameter.kind == NodeKind.Function) {
                 renderFunction(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name))
-            }
-            else {
+            } else {
                 renderProperty(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name))
             }
         }
@@ -102,7 +101,7 @@
         fun renderReceiver(receiver: DocumentationNode, to: ContentBlock)
     }
 
-    private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String): SignatureMapper {
+    private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String) : SignatureMapper {
         override fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) {
             to.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName))
             to.text("<$typeParameterName>")
@@ -116,7 +115,7 @@
     }
 
     private fun <T> ContentBlock.renderList(nodes: List<T>, separator: String = ", ",
-                                        noWrap: Boolean = false, renderItem: (T) -> Unit) {
+                                            noWrap: Boolean = false, renderItem: (T) -> Unit) {
         if (nodes.none())
             return
         renderItem(nodes.first())
@@ -131,7 +130,7 @@
         }
     }
 
-    private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode)->Unit) {
+    private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode) -> Unit) {
         val to = node.links.firstOrNull()
         if (to == null)
             body(node)
@@ -215,13 +214,13 @@
 
     private fun ContentBlock.renderModifier(node: DocumentationNode, nowrap: Boolean = false) {
         when (node.name) {
-            "final", "public", "var" -> {}
+            "final", "public", "var" -> {
+            }
             else -> {
                 keyword(node.name)
                 if (nowrap) {
                     nbsp()
-                }
-                else {
+                } else {
                     text(" ")
                 }
             }
@@ -238,11 +237,12 @@
             nbsp()
             symbol(":")
             nbsp()
-            renderList(constraints, noWrap=true) {
+            renderList(constraints, noWrap = true) {
                 renderType(it, renderMode)
             }
         }
     }
+
     private fun ContentBlock.renderParameter(node: DocumentationNode, renderMode: RenderMode) {
         if (renderMode == RenderMode.FULL) {
             renderAnnotationsForNode(node)
@@ -401,8 +401,7 @@
             symbol(")")
             symbol(": ")
             renderType(node.detail(NodeKind.Type), renderMode)
-        }
-        else {
+        } else {
             symbol(")")
         }
         renderExtraTypeParameterConstraints(node, renderMode)
@@ -428,7 +427,7 @@
         }
     }
 
-    private fun needReturnType(node: DocumentationNode) = when(node.kind) {
+    private fun needReturnType(node: DocumentationNode) = when (node.kind) {
         NodeKind.Constructor -> false
         else -> !node.isUnitReturnType()
     }
@@ -475,4 +474,7 @@
     }
 }
 
-fun DocumentationNode.qualifiedNameFromType() = (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() ?: name
+fun DocumentationNode.qualifiedNameFromType() =
+        details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name
+                ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName()
+                ?: name
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index 897e3ad..4b10879 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -48,6 +48,7 @@
     Signature,
 
     ExternalLink,
+    QualifiedName,
     Platform,
 
     AllTypes,