diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,13 @@
-## [0.4.1.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.0.1) (2026-03-13)
+## [0.4.2.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.2.0) (2026-03-27)
+
+Fixed bugs:
+
+* [#63](https://github.com/PiotrJustyna/wyvern/issues/63) - clean up warnings
+* [#66](https://github.com/PiotrJustyna/wyvern/issues/66) - remove unused dependency: unordered-containers
+* [#67](https://github.com/PiotrJustyna/wyvern/issues/67) - connections overlapping
+* [#68](https://github.com/PiotrJustyna/wyvern/issues/68) - gamma connection routing + validation
+
+## [0.4.1.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.1.0) (2026-03-13)
 
 Fixed bug [#64](https://github.com/PiotrJustyna/wyvern/issues/64) - incorrect action token rendering.
 
diff --git a/diagrams/temp.svg b/diagrams/temp.svg
--- a/diagrams/temp.svg
+++ b/diagrams/temp.svg
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
-    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg font-size="1" viewBox="0.0 0.0 1920.0 1080.0" stroke="rgb(0,0,0)" xmlns="http://www.w3.org/2000/svg" width="1920.0000" stroke-opacity="1" height="1080.0000" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><defs></defs><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 960.0000,900.0000 v -720.0000 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 1824.0000,900.0000 h 0.0000 c 0.0000,-99.4113 -80.5887,-180.0000 -180.0000 -180.0000h -1368.0000 c -99.4113,-0.0000 -180.0000,80.5887 -180.0000 180.0000h 0.0000 c -0.0000,99.4113 80.5887,180.0000 180.0000 180.0000h 1368.0000 c 99.4113,0.0000 180.0000,-80.5887 180.0000 -180.0000Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="90.0px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.46441579677096"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,960.0000,900.0000)" stroke="none" dominant-baseline="middle" text-anchor="middle">end</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 1824.0000,180.0000 h 0.0000 c 0.0000,-99.4113 -80.5887,-180.0000 -180.0000 -180.0000h -1368.0000 c -99.4113,-0.0000 -180.0000,80.5887 -180.0000 180.0000h 0.0000 c -0.0000,99.4113 80.5887,180.0000 180.0000 180.0000h 1368.0000 c 99.4113,0.0000 180.0000,-80.5887 180.0000 -180.0000Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="90.0px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.46441579677096"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,960.0000,180.0000)" stroke="none" dominant-baseline="middle" text-anchor="middle">start</text></g></svg>
+    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg font-size="1" viewBox="0.0 0.0 1920.0 1080.0" stroke="rgb(0,0,0)" xmlns="http://www.w3.org/2000/svg" width="1920.0000" stroke-opacity="1" height="1080.0000" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><defs></defs><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1114.5316,477.7880 l -8.6203,4.9770 l 8.6203,4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,721.6590 v 159.2627 h 746.5438 v -398.1567 h -139.4939 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1413.1491,79.6313 l -8.6203,4.9770 l 8.6203,4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1701.5668,323.5023 v 159.2627 h 159.2627 v -398.1567 h -448.0654 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1030.2304 v 49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 199.6335,79.6313 l 8.6203,-4.9770 l -8.6203,-4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1080.0000 h -149.3088 v -1005.3456 h 140.6884 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,74.6544 h 1194.4700 v 24.8848 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,223.9631 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,323.5023 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,532.5346 v -209.0323 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,532.5346 h 0.0000 c 0.0000,-13.7435 -11.1413,-24.8848 -24.8848 -24.8848h -189.1244 c -13.7435,-0.0000 -24.8848,11.1413 -24.8848 24.8848h 0.0000 c -0.0000,13.7435 11.1413,24.8848 24.8848 24.8848h 189.1244 c 13.7435,0.0000 24.8848,-11.1413 24.8848 -24.8848Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,532.5346)" stroke="none" dominant-baseline="middle" text-anchor="middle">end</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1701.5668,423.0415 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,432.9954 v -9.9539 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1821.0138,447.9263 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1701.5668,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,447.9263 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1537.3272,313.5484)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1383.0415,363.3180)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1293.4562,348.3871 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">question - headline 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,248.8479 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,223.9631)" stroke="none" dominant-baseline="middle" text-anchor="middle">action - headline 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1283.5023,149.3088 v -49.7696 h 238.8940 v 49.7696 l -119.4470,9.9539 l -119.4470,-9.9539 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,124.4240)" stroke="none" dominant-baseline="middle" text-anchor="middle">headline 2</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,124.4240 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,223.9631 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,622.1198 v -398.1567 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,721.6590 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,930.6912 v -209.0323 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1030.2304 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 89.0323,1055.1152 v -49.7696 l 119.4470,-9.9539 l 119.4470,9.9539 v 49.7696 h -238.8940 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,1030.2304)" stroke="none" dominant-baseline="middle" text-anchor="middle">h2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,955.5760 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,930.6912)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 4</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,821.1982 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,831.1521 v -9.9539 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,821.1982 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 626.5438,846.0829 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,507.0968,821.1982)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 3</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,846.0829 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,821.1982)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,711.7051)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,761.4747)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,746.5438 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,721.6590)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,647.0046 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,622.1198)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 1</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,572.3502 h 597.2350 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,323.5023 v -99.5392 h -597.2350 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 v -199.0783 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,323.5023 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,572.3502 h 298.6175 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1104.3318,522.5806 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,522.5806 h 0.0000 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,522.5806 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1223.7788,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1104.3318,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 925.1613,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,940.0922,413.0876)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,785.8065,462.8571)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 696.2212,447.9263 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0b</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 925.1613,348.3871 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">action b</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,572.3502 h 298.6175 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,522.5806 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 h 0.0000 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 626.5438,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,507.0968,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,413.0876)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,462.8571)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,447.9263 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0a</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,348.3871 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">action a</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,214.0092)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,263.7788)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,248.8479 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,223.9631)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 89.0323,149.3088 v -49.7696 h 238.8940 v 49.7696 l -119.4470,9.9539 l -119.4470,-9.9539 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,124.4240)" stroke="none" dominant-baseline="middle" text-anchor="middle">headline 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,24.8848 h 0.0000 c 0.0000,-13.7435 -11.1413,-24.8848 -24.8848 -24.8848h -189.1244 c -13.7435,-0.0000 -24.8848,11.1413 -24.8848 24.8848h 0.0000 c -0.0000,13.7435 11.1413,24.8848 24.8848 24.8848h 189.1244 c 13.7435,0.0000 24.8848,-11.1413 24.8848 -24.8848Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,24.8848)" stroke="none" dominant-baseline="middle" text-anchor="middle">start</text></g></svg>
diff --git a/diagrams/temp.txt b/diagrams/temp.txt
--- a/diagrams/temp.txt
+++ b/diagrams/temp.txt
@@ -1,9 +1,45 @@
-"action 1"
-"question 1"
+h1 "headline 1"
 {
-    123 456"action 2"
+    0 "question 0"
+    {
+        0a "action a"
+        0aq "question 0a"
+        {
+            0aqa1 "unknown action"
+        }
+        {
+            0aqa2 "unknown action"
+        }
+    }
+    {
+        0b "action b"
+        0bq "question 0b"
+        {
+            0bqa1 "unknown action"
+        }
+        {
+            0bqa2 "unknown action"
+        }
+    }
+    1 "action 1"
+    q1 "question 1"
+    {
+        123 "action 2"
+    }
+    {
+        "action 3" 0bqa2
+    }
+    4 "action 4"
+    h2
 }
+h2 "headline 2"
 {
-    "action 3"
+    "action - headline 2"
+    "question - headline 2"
+    {
+        "action 1"
+    }
+    {
+        "action 2" h2
+    }
 }
-"action 4"
diff --git a/src/app/Main.hs b/src/app/Main.hs
--- a/src/app/Main.hs
+++ b/src/app/Main.hs
@@ -1,6 +1,6 @@
 module Main where
 
-import Blocks (render)
+import Blocks (renderDiagram, validateBlocks)
 import Constants (svgOptions)
 import Diagrams.Backend.SVG (renderSVG')
 import InputArguments (inputPath, outputPath, parseInput)
@@ -8,29 +8,36 @@
 import Options.Applicative (execParser, fullDesc, header, helper, info, (<**>))
 import Parser (ParseResult (..), diagram)
 
-main :: IO ()
+main :: IO Int
 main = do
   input <- execParser options
   print input
   fileContent <- readFile $ inputPath input
 
-  -- lexer v1/v2
-  -- let tokens = alexScanTokens fileContent
-
-  -- putStrLn "tokens:"
-  -- print tokens
-
-  -- lexer v3
   let lexingResult = runAlex fileContent lexAll
 
   case lexingResult of
-    Left lexingError -> do
-      putStrLn $ "Wyvern failed with the following error: " <> lexingError
-    Right tokens -> do
-      -- print tokens
-      case diagram tokens 1 of
-        ParseOk d -> renderSVG' (outputPath input) svgOptions (Blocks.render d)
-        ParseFail s -> error s
+    Left lexingError ->
+      do
+        putStrLn $ "Wyvern failed with the following error: " <> lexingError
+        return 1
+    Right tokens ->
+      do
+        case diagram tokens 1 of
+          ParseOk blocks -> do
+            case validateBlocks blocks of
+              Left validBlocks ->
+                do
+                  renderSVG' (outputPath input) svgOptions (Blocks.renderDiagram validBlocks)
+                  return 0
+              Right (errors, ids) ->
+                do
+                  putStrLn "Diagram validation failed with the following error(s):"
+                  print errors
+                  putStrLn "Available block identifiers to be used as gamma connections destinations:"
+                  print ids
+                  return 1
+          ParseFail s -> error s
   where
     options =
       info
diff --git a/src/lib/Blocks.hs b/src/lib/Blocks.hs
--- a/src/lib/Blocks.hs
+++ b/src/lib/Blocks.hs
@@ -1,14 +1,10 @@
 module Blocks where
 
-import Constants (defaultBoundingBoxHeight, defaultBoundingBoxWidth, heightRatio, widthRatio)
-import Data.HashSet (HashSet, insert, member)
-import Data.List (groupBy, sortBy, sortOn)
+import Constants (defaultBoundingBoxHeight, defaultBoundingBoxWidth)
 import Data.Map (Map, empty, insert, lookup)
-import Data.Ord (comparing)
 import Diagrams.Backend.SVG (B)
-import Diagrams.Prelude (Diagram, Point (..), V2 (..), p2, position, r2, translate, (#))
-import GHC.Float
-import HelperDiagrams (renderConnection, renderGammaConnection, renderLowerBetaConnections, renderSideBetaConnection, renderText, renderUpperBetaConnections, wyvernAddress, wyvernHeadline, wyvernQuestion, wyvernRect, wyvernRoundedRect)
+import Diagrams.Prelude (Diagram, Point (..), V2 (..), p2, position)
+import HelperDiagrams (renderConnection, renderGammaConnection, renderLowerBetaConnections, renderSideBetaConnection, renderUpperBetaConnections, wyvernAddress, wyvernHeadline, wyvernQuestion, wyvernRect, wyvernRoundedRect)
 import ID
 
 data Block
@@ -25,7 +21,7 @@
   foldl
     ( \accu x ->
         case x of
-          Fork id content l r rId -> Fork id content (reverse' l) (reverse' r) rId : accu
+          Fork i content l r rId -> Fork i content (reverse' l) (reverse' r) rId : accu
           _ -> x : accu
     )
     []
@@ -55,6 +51,17 @@
 getIdentifier (Address i _) = i
 getIdentifier (Fork i _ _ _ _) = i
 
+getAllIdentifiers' :: [Block] -> [ID]
+getAllIdentifiers' = foldr (\singleBlock accu -> getAllIdentifiers singleBlock <> accu) []
+
+getAllIdentifiers :: Block -> [ID]
+getAllIdentifiers (Fork (Just i) _ l r _) = getAllIdentifiers' l <> getAllIdentifiers' r <> [i]
+getAllIdentifiers (Fork Nothing _ l r _) = getAllIdentifiers' l <> getAllIdentifiers' r
+getAllIdentifiers b =
+  case getIdentifier b of
+    Just i -> [i]
+    Nothing -> []
+
 renderSingleBlock ::
   Block ->
   Point V2 Double ->
@@ -62,16 +69,16 @@
   [(Point V2 Double, Double, Double, ID)] ->
   Double ->
   (Diagram B, Map ID (Point V2 Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, Double)
-renderSingleBlock fork@(Fork i c l r gCId) o@(P (V2 oX oY)) ds gCs globalMaxWidth =
+renderSingleBlock (Fork _i c l r gCId) o@(P (V2 oX oY)) ds gCs globalMaxWidth =
   let (gCW, gCH) = case gCId of
         Nothing -> (0.0, 0.0)
         Just _ -> (0.1, 0.1)
-      (dQ, wQ, hQ) = (position [(o, wyvernQuestion c)], oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+      (dQ, _wQ, hQ) = (position [(o, wyvernQuestion c)], oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
       lX = oX
       lY = hQ
       rX = maxWL
       rY = hQ
-      (dL, dsL, gCsL, wL, hL, maxWL, minHL) = renderSingleSkewer l (p2 (lX, lY)) ds gCs 0.0
+      (dL, dsL, gCsL, _wL, _hL, maxWL, minHL) = renderSingleSkewer l (p2 (lX, lY)) ds gCs 0.0
       (dR, dsR, gCsR, wR, hR, maxWR, minHR) = renderSingleSkewer r (p2 (rX, if null r then oY else rY)) dsL gCsL globalMaxWidth
       newMaxW = maxWR + gCW
       newMaxW' = max newMaxW globalMaxWidth
@@ -96,11 +103,11 @@
         newMaxW',
         newMinH
       )
-renderSingleBlock StartTerminator o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRoundedRect $ getContent StartTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
-renderSingleBlock EndTerminator o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRoundedRect $ getContent EndTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
-renderSingleBlock (Headline _i c) o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernHeadline c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
-renderSingleBlock (Address _i c) o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernAddress c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
-renderSingleBlock b o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRect $ getContent b)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+renderSingleBlock StartTerminator o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRoundedRect $ getContent StartTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+renderSingleBlock EndTerminator o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRoundedRect $ getContent EndTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+renderSingleBlock (Headline _i c) o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernHeadline c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+renderSingleBlock (Address _i c) o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernAddress c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
+renderSingleBlock b o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRect $ getContent b)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)
 
 renderSingleSkewer ::
   [Block] ->
@@ -109,19 +116,19 @@
   [(Point V2 Double, Double, Double, ID)] ->
   Double ->
   (Diagram B, Map ID (Point V2 Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, Double)
-renderSingleSkewer [] o@(P (V2 oX oY)) ds gCs globalWidth =
+renderSingleSkewer [] (P (V2 oX oY)) ds gCs globalWidth =
   let w = oX
       minD = oY
       localWidth = w + defaultBoundingBoxWidth
       localWidth' = max globalWidth localWidth
    in (mempty, ds, gCs, w, minD, localWidth', minD)
-renderSingleSkewer [b] o@(P (V2 oX oY)) ds gCs globalWidth =
+renderSingleSkewer [b] o@(P (V2 oX _oY)) ds gCs globalWidth =
   let ds' = updateDestinations (getIdentifier b) o ds
-      (d, ds'', gCs', w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth
+      (d, ds'', gCs', _w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth
    in (d, ds'', gCs', oX, h, maxW, minH)
 renderSingleSkewer (b : bs) o@(P (V2 oX oY)) ds gCs globalWidth =
   let ds' = updateDestinations (getIdentifier b) o ds
-      (d, ds'', gCs', w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth
+      (d, ds'', gCs', _w, _h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth
       (d', ds''', gCs'', w', h', maxW', minH') = renderSingleSkewer bs (p2 (oX, minH)) ds'' gCs' (maxW + 0.1)
    in (d <> d' <> renderConnection [p2 (oX, minH), p2 (oX, oY)], ds''', gCs'', w', h', max maxW maxW', minH')
 
@@ -136,26 +143,27 @@
   [[Block]] ->
   (Diagram B, Map ID (Point V2 Double), ([(Double, Double)], [(Double, Double, Double)], Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, [[Block]])
 renderAllSkewers' rD ds bCs gCs w h maxH [] = (rD, ds, bCs, gCs, w, h, maxH, [])
-renderAllSkewers' accuRD accuDs accuBCs@(uBCs, lBCs, minD) accuGCs accuW accuH accuMaxH [b] =
-  let (rD, ds, gCs, w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW
+renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH _accuMaxH [b] =
+  let (rD, ds, gCs, _w, _h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW
    in renderAllSkewers' (accuRD <> rD) ds (uBCs, lBCs, min minD maxH) gCs maxW accuH (min minD maxH) []
-renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH accuMaxH (b : bs) =
-  let (rD, ds, gCs, w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW
+renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH _accuMaxH (b : bs) =
+  let (rD, ds, gCs, _w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW
    in renderAllSkewers' (accuRD <> rD) ds ((accuW, maxW) : uBCs, (accuW, maxW, h) : lBCs, min minD maxH) gCs maxW accuH (min minD maxH) bs
 
 renderAllSkewers :: [[Block]] -> (Diagram B, Map ID (Point V2 Double), ([(Double, Double)], [(Double, Double, Double)], Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, [[Block]])
+renderAllSkewers [] = error "no skewers provided"
 renderAllSkewers blocks@(b : bs) =
   let manyBlocks = length blocks > 2
-      (rD, ds, (uBCs, lBCs, minD), gCs, w, h, maxH, _) = renderAllSkewers' mempty Data.Map.empty ([], [], 0.0) [] 0.0 0.0 0.0 [b]
+      (rD, ds, (uBCs, lBCs, minD), gCs, w, _h, maxH, _) = renderAllSkewers' mempty Data.Map.empty ([], [], 0.0) [] 0.0 0.0 0.0 [b]
       uBCs' = if null bs then uBCs else (0.0, w) : uBCs
       lBCs' = if null bs then lBCs else (0.0, w, maxH) : lBCs
       (rD', ds', (uBCs'', lBCs'', minD'), gCs', w', h', maxH', _) = renderAllSkewers' rD ds (uBCs', lBCs', minD) gCs w (negate defaultBoundingBoxHeight) maxH bs
    in (rD', ds', (uBCs'', lBCs'', minD'), gCs', w', h', if manyBlocks then maxH' else maxH, b : bs)
 
-render' :: [[Block]] -> Diagram B
-render' [] = mempty
-render' bs =
-  let (rD', ds', (uBCs, lBCs, minD), gCs', w', h', maxH', _) = renderAllSkewers bs
+renderDiagram' :: [[Block]] -> Diagram B
+renderDiagram' [] = mempty
+renderDiagram' bs =
+  let (rD', ds', (uBCs, lBCs, _minD), gCs', _w', _h', maxH', _) = renderAllSkewers bs
       bCs = case length bs of
         1 -> mempty
         _ ->
@@ -172,9 +180,49 @@
         (rD' <> bCs)
         gCs'
 
-render :: [[Block]] -> Diagram B
-render [] = mempty
-render [b] = render' $ Blocks.reverse [(EndTerminator : b) <> [StartTerminator]]
-render bs =
-  let bs' = tail bs
-   in render' . Blocks.reverse $ ((EndTerminator : head bs) : init bs') <> [last bs' <> [StartTerminator]]
+renderDiagram :: [[Block]] -> Diagram B
+renderDiagram [] = mempty
+renderDiagram [b] = renderDiagram' $ Blocks.reverse [(EndTerminator : b) <> [StartTerminator]]
+renderDiagram (b : bs) = renderDiagram' . Blocks.reverse $ ((EndTerminator : b) : init bs) <> [last bs <> [StartTerminator]]
+
+validateSingleBlock :: Block -> [ID] -> (Bool, String)
+validateSingleBlock (Fork (Just i) _ _ _ (Just gCId)) ids = if gCId == i || gCId `elem` ids then (True, "") else (False, "Gamma connection ID: " <> show gCId <> " does not exist in the collection of block identifiers.")
+validateSingleBlock (Fork Nothing _ _ _ (Just gCId)) ids = if gCId `elem` ids then (True, "") else (False, "Gamma connection ID: " <> show gCId <> " does not exist in the collection of block identifiers.")
+validateSingleBlock (Fork _ _ _ _ Nothing) _ = (True, "")
+validateSingleBlock _ _ = (True, "")
+
+validateBlocks' :: [Block] -> Either [Block] ([String], [ID])
+validateBlocks' [] = Left []
+validateBlocks' [b] = Left [b]
+validateBlocks' bs =
+  let (errors, ids) =
+        foldr
+          ( \singleBlock (accuErrors, accuIds) ->
+              let (isValid, errorMessage) = validateSingleBlock singleBlock accuIds
+               in (if isValid then accuErrors else errorMessage : accuErrors, getAllIdentifiers singleBlock <> accuIds)
+          )
+          ([], [])
+          bs
+   in case errors of
+        [] -> Left bs
+        _ -> Right (errors, ids)
+
+validateBlocks :: [[Block]] -> Either [[Block]] ([String], [ID])
+validateBlocks [] = Left []
+validateBlocks (b : []) =
+  case validateBlocks' b of
+    Left b' -> Left [b']
+    Right errors -> Right errors
+validateBlocks bs =
+    let validationResult@(allErrors, allIds) =
+                                foldl
+                                ( \accu@(accuErrors, accuIds) b ->
+                                    case validateBlocks' b of
+                                        Left _ -> accu
+                                        Right (errors, ids) -> (errors <> accuErrors, ids <> accuIds)
+                                )
+                                ([], [])
+                                bs
+    in case allErrors of
+        [] -> Left bs
+        _ -> Right validationResult
diff --git a/src/lib/Constants.hs b/src/lib/Constants.hs
--- a/src/lib/Constants.hs
+++ b/src/lib/Constants.hs
@@ -1,7 +1,6 @@
 module Constants where
 
 import Data.Colour.SRGB (sRGB)
-import Data.Text (empty)
 import Diagrams.Backend.SVG
   ( B,
     Options (SVGOptions),
@@ -50,7 +49,6 @@
 svgOptions =
   SVGOptions
     { _size = mkSizeSpec $ V2 (Just 1920) (Just 1080),
-      _idPrefix = empty,
       _svgDefinitions = Nothing,
       _svgAttributes = [],
       _generateDoctype = True
diff --git a/src/lib/HelperDiagrams.hs b/src/lib/HelperDiagrams.hs
--- a/src/lib/HelperDiagrams.hs
+++ b/src/lib/HelperDiagrams.hs
@@ -128,12 +128,19 @@
 renderConnection :: [Point V2 Double] -> Diagram B
 renderConnection coordinates = fromVertices coordinates # wyvernStyle
 
+-- 2026-03-25 PJ:
+-- ##############
+-- TODO:
+
+-- * we need a max x for the destination block
+
+--   we only have the max x for the origin block
 renderGammaConnection :: Point V2 Double -> Point V2 Double -> Double -> Double -> Diagram B
 renderGammaConnection gO@(P (V2 gOX gOY)) gD@(P (V2 gDX gDY)) maxX minY =
-  let gD'@(P (V2 gDX' gDY')) = p2 (gDX + (0.1 * sqrt 3.0 / 2.0) + 0.012, gDY + defaultBoundingBoxHeight * 0.5)
+  let gD'@(P (V2 gDX' gDY')) = p2 (gDX + (0.1 * sqrt 3.0 / 2.0) + 0.012, gDY + defaultBoundingBoxHeight * 0.5 - 0.1)
       gammaMidpoint1 = p2 (gOX, minY)
-      gammaMidpoint2 = p2 (maxX - defaultBoundingBoxWidth * 0.5, minY)
-      gammaMidpoint3 = p2 (maxX - defaultBoundingBoxWidth * 0.5, gDY')
+      gammaMidpoint2 = p2 (if gDX > gOX then gDX + defaultBoundingBoxWidth * 0.5 else maxX - defaultBoundingBoxWidth * 0.5, minY)
+      gammaMidpoint3 = p2 (if gDX > gOX then gDX + defaultBoundingBoxWidth * 0.5 else maxX - defaultBoundingBoxWidth * 0.5, gDY')
       coordinates = [gO, gammaMidpoint1, gammaMidpoint2, gammaMidpoint3, gD']
    in renderConnection coordinates <> position [(p2 (gDX' - 0.025, gDY'), rotateBy (1 / 4) $ triangle 0.1 # wyvernStyle)]
 
@@ -145,7 +152,7 @@
       p2 (uBCb, maxD + defaultBoundingBoxHeight * 0.5),
       p2 (uBCb, maxD + defaultBoundingBoxHeight * heightRatio * 0.5)
     ]
-renderUpperBetaConnections (uBC@(uBCa, uBCb) : uBCs) maxD =
+renderUpperBetaConnections ((uBCa, uBCb) : uBCs) maxD =
   renderConnection
     [ p2 (uBCa, maxD + defaultBoundingBoxHeight * 0.5),
       p2 (uBCb, maxD + defaultBoundingBoxHeight * 0.5),
@@ -154,7 +161,7 @@
     <> renderUpperBetaConnections uBCs maxD
 
 renderSideBetaConnection :: Point V2 Double -> Point V2 Double -> Diagram B
-renderSideBetaConnection a@(P (V2 aX aY)) b@(P (V2 bX bY)) =
+renderSideBetaConnection a@(P (V2 aX aY)) (P (V2 bX bY)) =
   renderConnection
     [ a,
       p2 (aX - defaultBoundingBoxWidth * 0.5, aY),
@@ -165,12 +172,12 @@
 
 renderLowerBetaConnections' :: [(Double, Double, Double)] -> Double -> Diagram B
 renderLowerBetaConnections' [] _ = mempty
-renderLowerBetaConnections' (lBC@(lBCa, lBCb, lBCc) : lBCs) minD =
+renderLowerBetaConnections' ((lBCa, lBCb, lBCc) : lBCs) minD =
   renderConnection [p2 (lBCa, lBCc + defaultBoundingBoxHeight), p2 (lBCa, minD), p2 (lBCb, minD)]
     <> renderLowerBetaConnections' lBCs minD
 
 renderLowerBetaConnections :: [(Double, Double, Double)] -> Double -> Diagram B
 renderLowerBetaConnections [] _ = mempty
-renderLowerBetaConnections (lBC@(lBCa, lBCb, lBCc) : lBCs) minD =
+renderLowerBetaConnections ((lBCa, _lBCb, lBCc) : lBCs) minD =
   renderConnection [p2 (lBCa, lBCc + defaultBoundingBoxHeight), p2 (lBCa, minD)]
     <> renderLowerBetaConnections' lBCs minD
diff --git a/src/lib/ID.hs b/src/lib/ID.hs
--- a/src/lib/ID.hs
+++ b/src/lib/ID.hs
@@ -2,7 +2,6 @@
 
 newtype ID
   = ID String
-  deriving (Show)
 
 instance Eq ID where
   (==) (ID a) (ID b) = a == b
@@ -15,3 +14,6 @@
   (<=) (ID a) (ID b) = a <= b
   min (ID a) (ID b) = ID $ min a b
   max (ID a) (ID b) = ID $ max a b
+
+instance Show ID where
+  show (ID x) = show x
diff --git a/wyvern-diagrams.cabal b/wyvern-diagrams.cabal
--- a/wyvern-diagrams.cabal
+++ b/wyvern-diagrams.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.4
 name:               wyvern-diagrams
-version:            0.4.1.0
+version:            0.4.2.0
 synopsis:           Simple flowchart diagrams. Inspired by DRAKON.
 description:        Wyvern combines syntax and rendering engine
                     for simple, DRAKON-like flowcharts.
@@ -38,8 +38,6 @@
                       base >= 4.19.2.0 && < 5,
                       -- MIT
                       colour >= 2.3.6 && < 3,
-                      -- BSD-2-Clause
-                      text >= 2.1.2 && < 3,
                       -- BSD-3-Clause
                       diagrams-lib >= 1.5.1 && < 2,
                       -- BSD-3-Clause
@@ -47,11 +45,11 @@
                       -- BSD-3-Clause
                       containers >= 0.7 && < 1,
                       -- BSD-3-Clause
+                      -- Used in Parser.
                       MissingH >= 1.6.0 && < 2,
                       -- BSD-3-Clause
+                      -- Used in Lexer.
                       array >= 0.5.8 && < 1,
-                      -- BSD-3-Clause
-                      unordered-containers >= 0.2.21 && < 1,
                       -- BSD-3-Clause
                       optparse-applicative >= 0.19.0 && < 1
     default-language: Haskell2010
