func visualize(threads jwz.Threadable) {
	root := tview.NewTreeNode("Threads").
		SetColor(tcell.ColorGreen)
	buildVisual(root, threads)
	tree := tview.NewTreeView().
		SetRoot(root).
		SetCurrentNode(root)
	sideBar := tview.NewTextView().
		SetTextAlign(tview.AlignLeft).
		SetText("Email Text")
	headers := tview.NewTextView().
		SetTextAlign(tview.AlignLeft).
		SetText("Email Headers").
		SetToggleHighlights(false)
	tree.SetSelectedFunc(func(node *tview.TreeNode) {
		reference := node.GetReference()
		if reference == nil {
			sideBar.SetText("No email in this node")
		} else {
			thr := reference.(*Email)
			if thr.dummy {
				sideBar.SetText("Placeholders manufactured by the Threader don't contain email text")
			} else {
				sideBar.SetText(thr.email.Text)
				sideBar.ScrollToBeginning()
				headers.Clear()
				hk := thr.email.GetHeaderKeys()
				sort.Strings(hk)
				for _, k := range hk {
					v := thr.email.GetHeader(k)
					if !strings.HasPrefix(k, "From ") {
						_, _ = headers.Write([]byte(fmt.Sprintf("%-30s: %s\n", k, v)))
						headers.ScrollToBeginning()
					}
				}
			}
		}
	})
	grid := tview.NewGrid().
		SetRows(-3, 0).
		SetColumns(-0, -2).
		SetBorders(true).
		AddItem(headers, 1, 0, 1, 2, 0, 0, false)
	grid.AddItem(tree, 0, 0, 1, 1, 5, 50, true).
		AddItem(sideBar, 0, 1, 1, 1, 0, 50, false)
	flex := tview.NewFlex().SetDirection(tview.FlexRow)
	flex.AddItem(tree, 0, 2, true)
	text := tview.NewBox().SetBorder(false)
	flex.AddItem(text, 0, 3, false)
	info := tview.NewBox().SetBorder(true)
	flex.AddItem(info, 7, 1, false)
	app := tview.NewApplication().SetRoot(grid, true).EnableMouse(true)
	if err := app.Run(); err != nil {
		panic(err)
	}
}
visualize a neat-ish ASCII tree representation of the threads, so we can do a human based check of whether
things are working.

Also, The colors will sometimes look wonky on a custom configuration of OSX console. Try a standard one and
make sure your TERM and terminfo database are good if you have issues.
package main
import (
	"flag"
	"fmt"
	"github.com/gatherstars-com/jwz"
	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
	"log"
	"os"
	"sort"
	"strings"
)
func main() {
	var testData string
	var sizeHint int
	flag.StringVar(&testData, "emldir", "./eml", "base directory beneath which the test can find .eml files")
	flag.IntVar(&sizeHint, "sizehint", 3000, "supply a rough number of the emails you are scanning, if you have a clue")
	flag.Parse()
	threadables, err := buildEnvelopes(testData, sizeHint)
	if err != nil {
		log.Printf("Unable to walk the eml directory: %#v", err)
		os.Exit(1)
	}
	threader := jwz.NewThreader()
	sliceRoot, err := threader.ThreadSlice(threadables)
	if err != nil {
		log.Fatalf("Email threading operation return fatal error: %#v", err)
	}
	x := jwz.Sort(sliceRoot, byDate)
	visualize(x)
}