--- a/LIME-core/lib/gxfdump.awk
+++ b/LIME-core/lib/gxfdump.awk
@@ -1,5 +1,9 @@
 #!/usr/bin/awk -f
 ##################################################################
+# This AWK script implements generation of .dot files from .gxf
+#
+#Copyright 2008 Pjotr Kourzanov
+#
 #This file is part of LIME.
 #
 #LIME is free software: you can redistribute it and/or modify
@@ -16,9 +20,42 @@
 ##################################################################
 BEGIN { if (!OP) OP="dump" }
 
-func handle(tag,body) { return handle_gxf(tag,body) }
-
-func fifoidx(f,c,p, r) { r=fifo_idx[f,c,p]; return r > 0 ? r-1 : port_idx[f,c,p]-1 }
+func handle(tag,body) { return handle_bindings(tag,handle_gxf(tag,body)) }
+
+func handle_bindings(t,b, n) {
+#   if (DEBUG) print "BINDINGS: handling",t,"in",state >STDERR
+
+    if (handle_xlink(t,b)) return b
+
+    if (t=="bound-to" && state ~ /@node$/) {
+    	n=id[lev]
+    	gsub(n ":","",from[lev+1])
+    	gsub(n ":","",to[lev+1])
+        #print n,from[lev+1],to[lev+1] >STDERR
+	int_edge[n,++nint_edge[n]]=from[lev+1] SUBSEP to[lev+1]
+	delete from; delete to
+    	return b
+    }
+
+    if (t=="node" && state==root) {
+    	return b
+    }
+
+    if (relax) {
+#    	if (DEBUG) print "BINDINGS: ignoring",tag,"in",state >STDERR
+    	return b
+    }
+
+    fail("BINDINGS: unknown tag " t)
+    return b
+}
+
+func fifoidx(f,c,p, r) { r=fifo_idx[f,c,p]
+	if (r>0) return r-1
+	r=port_idx[f,c,p]
+	if (r>0) return r-1
+	return ""
+}
 
 END { if (OP=="dump") for (f in files)  {
 	    print f,nnodes[f]
@@ -42,35 +79,160 @@
 }
 
 END { if (OP=="dot") for (f in files)  {
+      	    print "digraph",gensub(/\./,"_","g",f),"{ splines=polyline"
+	    for (i=1; i<=nnodes[f]; i++) {
+	    	n=nodes[f,i]
+		if (!fanout[f,n] && !fanin[f,n]) continue
+
+#"fontsize=26; "\
+		printf "subgraph cluster_%s { "\
+		       "rankdir=LR; "\
+		       "splines=line; "\
+		       "labelloc=%s; "\
+		       "label=\"%s\"; "\
+		       "style=filled\n", 
+		       dnode(n),
+		       (noutports[f,n]==0 ? "b" : "t"),
+		       dnode(n)
+
+
+	    if (node_detail) {
+		# Internal nodes
+		for (j=1; j<=nnodes[n]; j++)
+			prnode(n,nodes[n,j],1,n "_")
+		# Inner edges
+	    	for (j=1; j<=nedges[n]; j++) {
+	    	    split(edge_from[n,j],fr,SUBSEP)
+	    	    split(edge_to[n,j],to,SUBSEP)
+		    predge(n "_" fr[1],fr[2],n "_" to[1],to[2],n,j)
+	    	}
+		# bindings
+		for (j=1; j<=nint_edge[n]; j++) {
+			split(int_edge[n,j],ep,SUBSEP)
+			print n "_" ep[1],"->", n "_" ep[2],"[arrowhead=none]"
+		}
+	    }
+
+		# Outer ports
+		print "{ rank=source"
+	        for (j=1; j<=ninports[f,n]; j++) {
+		   p=inports[f,n,j]
+		   printf "%s_%s [fontsize=8 style=filled color=white shape=\"%s\" label=\"%s\"]\n",
+			dnode(n),p,
+		        "trapezium",
+			(1 ? p : port_type[f,n,p] " " p	dotconv(get_portsizes(f,n,p)))
+		}
+		print "}"
+		print "{ rank=sink"
+	        for (j=1; j<=noutports[f,n]; j++) {
+		   p=outports[f,n,j]
+		   printf "%s_%s [fontsize=8 style=filled color=white shape=\"%s\" label=\"%s\"]\n",
+			dnode(n),p,
+		        "invtrapezium",
+			(1 ? p : port_type[f,n,p] " " p	dotconv(get_portsizes(f,n,p)))
+		}
+		print "}"
+
+		# find local state self-references in this node
+	if (!node_detail) for (j=1; j<=nnodes[n]; j++) {
+			sn=nodes[n,j]
+			for (k=1; k<=nstateports[n,sn,"read"]; k++) {
+			    p=stateports[n,sn,"read",k]
+			    if (peer_node[n,sn,p]==sn)
+			    {
+			      if(peer_dir[n,sn,p]=="read")
+				predge(n,peer_port[n,sn,p],n,p,n,peer_edge[n,sn,p],"_")
+			      else 
+				predge(n,p,n,peer_port[n,sn,p],n,peer_edge[n,sn,p],"_")
+			    }
+			}
+		}
+		print "}"
+	    }
+	    for (i=1; i<=nedges[f]; i++) {
+	    	split(edge_from[f,i],fr,SUBSEP)
+	    	split(edge_to[f,i],to,SUBSEP)
+		prEdge(fr[1],fr[2],to[1],to[2],f,i,"_")
+	    }
+	    print "}"
+      }
+}
+
+func prnode(f,n,not,pr, done,j,p)
+{
+	printf "%s%s [shape=record label=\"{",pr,dnode(n)
+	done=0
+        for (j=1; j<=ninports[f,n]; j++) {
+	   p=inports[f,n,j]
+	   printf "%s <%s> %s",
+		(done ? "|" : "{"),
+		p,
+		(not ? p : port_type[f,n,p] " " p dotconv(get_portsizes(f,n,p)))
+	   done=1
+	}
+	printf "%s %s()",(done ? " } |" : ""),dnode(n)
+	done=0
+        for (j=1; j<=noutports[f,n]; j++) {
+	   p=outports[f,n,j]
+	   printf "%s <%s> %s",
+		(done ? "|" : "| {"),
+		p,
+		(not ? p : port_type[f,n,p] " " p dotconv(get_portsizes(f,n,p)))
+	   done=1
+	}
+	printf "%s",(done ? "}" : "")
+
+	print "}\"]"
+}
+func dotconv(s) {
+	return gensub(/[<>]/,"\\\\&","g",s)
+}
+func prEdge(fn,fp,tn,tp,f,i,sep) {
+	if (edge_detail) return predge_detail(fn,fp,tn,tp,f,i,sep)
+	return predge(fn,fp,tn,tp,f,i,sep)
+}
+
+func predge_detail(fn,fp,tn,tp,f,i,sep) {
+	if (!sep) sep=":"
+	printf "%s_%i [label=\"{ {<in> %s%s} | %s | {<out> %s%s} }\" shape=record]\n",
+		edge_type[f,i],
+		++number[edge_type[f,i]],
+		port_type[f,fn,fp],dotconv(get_portsizes(f,fn,fp)),
+		edge_type[f,i],
+		port_type[f,tn,tp], dotconv(get_portsizes(f,tn,tp))
+    	printf "%s%s%s -> %s_%i:in%s [%s]\n",
+		dnode(fn),sep,fp,
+		edge_type[f,i], number[edge_type[f,i]],
+		(1 ? "" : ":n"),
+		tn!=fn ? "taillabel=\"" fifoidx(f,fn,fp) "\"" : ""
+    	printf "%s_%i:out%s -> %s%s%s [%s]\n",
+		edge_type[f,i], number[edge_type[f,i]],
+		(1 ? "" : ":s"),
+		dnode(tn),sep,tp,
+		tn!=fn ? "headlabel=\"" fifoidx(f,tn,tp) "\"" : ""
+}
+func predge(fn,fp,tn,tp,f,i,sep) {
+	if (!sep) sep=":"
+    	printf "%s%s%s -> %s%s%s [%s %s %s]\n",
+		dnode(fn),sep,fp,
+		dnode(tn),sep,tp,
+		edgetype(f,i),
+		tn==fn ? "" : "headlabel=\"" fifoidx(f,tn,tp) "\"",
+		tn==fn ? "" : "taillabel=\"" fifoidx(f,fn,fp) "\""
+}
+
+func edgetype(f,i) {
+	return edge_type[f,i] ? "label=\"" edge_type[f,i] "\"" : ""
+}
+
+func dnode(n) { return gensub(/[@\$]/,"_","g",n) }
+
+END { if (OP=="dot2") for (f in files)  {
       	    print "digraph",gensub(/\./,"_","g",f),"{"
 	    for (i=1; i<=nnodes[f]; i++) {
 	    	n=nodes[f,i]
 		if (!fanout[f,n] && !fanin[f,n]) continue
-		printf "%s [shape=record label=\"{",dnode(n)
-		done=0
-	        for (j=1; j<=ninports[f,n]; j++) {
-		   p=inports[f,n,j]
-		   printf "%s <%s> %s %s%s",
-			(done ? "|" : "{"),
-			p,
-			port_type[f,n,p],p,
-			get_portsizes(f,n,p)
-		   done=1
-		}
-		printf "%s %s",(done ? " } |" : ""),"\\N"
-		done=0
-	        for (j=1; j<=noutports[f,n]; j++) {
-		   p=outports[f,n,j]
-		   printf "%s <%s> %s %s%s",
-			(done ? "|" : "| {"),
-			p,
-			port_type[f,n,p],p,
-			get_portsizes(f,n,p)
-		   done=1
-		}
-		printf "%s",(done ? "}" : "")
-
-		print "}\"]"
+		prnode(f,n)
 
 		# find local state self-references in this node
 		for (j=1; j<=nnodes[n]; j++) {
@@ -96,74 +258,4 @@
       }
 }
 
-END { if (OP=="dot2") for (f in files)  {
-      	    print "digraph",gensub(/\./,"_","g",f),"{"
-	    for (i=1; i<=nnodes[f]; i++) {
-	    	n=nodes[f,i]
-		if (!fanout[f,n] && !fanin[f,n]) continue
-		printf "%s [shape=record label=\"{",dnode(n)
-		done=0
-	        for (j=1; j<=ninports[f,n]; j++) {
-		   p=inports[f,n,j]
-		   printf "%s <%s> %s %s%s",
-			(done ? "|" : "{"),
-			p,
-			port_type[f,n,p],p,
-			get_portsizes(f,n,p)
-		   done=1
-		}
-		printf "%s %s",(done ? " } |" : ""),"\\N"
-		done=0
-	        for (j=1; j<=noutports[f,n]; j++) {
-		   p=outports[f,n,j]
-		   printf "%s <%s> %s %s%s",
-			(done ? "|" : "| {"),
-			p,
-			port_type[f,n,p],p,
-			get_portsizes(f,n,p)
-		   done=1
-		}
-		printf "%s",(done ? "}" : "")
-
-		print "}\"]"
-
-		# find local state self-references in this node
-		for (j=1; j<=nnodes[n]; j++) {
-			sn=nodes[n,j]
-			for (k=1; k<=nstateports[n,sn,"read"]; k++) {
-			    p=stateports[n,sn,"read",k]
-			    if (peer_node[n,sn,p]==sn)
-			    {
-			      if(peer_dir[n,sn,p]=="read")
-				predge(n,peer_port[n,sn,p],n,p,n,peer_edge[n,sn,p])
-			      else 
-				predge(n,p,n,peer_port[n,sn,p],n,peer_edge[n,sn,p])
-			    }
-			}
-		}
-	    }
-	    for (i=1; i<=nedges[f]; i++) {
-	    	split(edge_from[f,i],fr,SUBSEP)
-	    	split(edge_to[f,i],to,SUBSEP)
-		predge(fr[1],fr[2],to[1],to[2],f,i)
-	    }
-	    print "}"
-      }
-}
-
-func predge(fn,fp,tn,tp,f,i) {
-    	printf "%s:%s -> %s:%s [%s %s %s]\n",
-		dnode(fn),fp,
-		dnode(tn),tp,
-		edgetype(f,i),
-		tn==fn ? "" : "headlabel=\"" fifoidx(f,tn,tp) "\"",
-		tn==fn ? "" : "taillabel=\"" fifoidx(f,fn,fp) "\""
-}
-
-func edgetype(f,i) {
-	return edge_type[f,i] ? "label=\"" edge_type[f,i] "\"" : ""
-}
-
-func dnode(n) { return gensub(/[@\$]/,"_","g",n) }
-
 @include gxf-parser.awk