Nearly every headless UI test opened with the same four-line prologue
(resolve the shared MainWindow, show it, cast its DataContext, wait for the
assembly list), then repeated the corelib lookup, the EnsureLazyChildren +
Children.OfType<T>().Single() drill, the registry single-by-header lookups,
and the open-an-assembly-and-wait dance. The duplication made the intent of
each test hard to see and every signature tweak a suite-wide edit.
Collapse those into TestHarness (BootAsync, OpenAssemblyAsync, GetCommand,
GetEntry) and TreeNavigation extensions (FindCoreLib, GetChild<T>, Expand<T>),
then apply them across the suite. Net ~865 lines of boilerplate removed with
no change in behaviour; the full headless suite stays green.
Browsing portable PDB metadata required drilling three levels deep:
Assembly → Metadata → Debug Directory → Debug Metadata (Embedded).
The PDB's tables are now exposed as a top-level MetadataTreeNode
alongside the host module's Metadata folder, so PDB browsing is one
click away. The PdbProvider already cached for decompilation is
reused — no second parse.
Assisted-by: Claude:claude-opus-4-7:Claude Code
DebugDirectoryTreeNode is now a lazy folder. Expanding it walks the
debug directory and adds a nested MetadataTreeNode per
EmbeddedPortablePdb entry, so the user can browse the debug-only
metadata tables (Document, MethodDebugInformation, …) the same way
they browse the host module's tables. The grid view (entry list) is
preserved when the node itself is clicked.
Assisted-by: Claude:claude-opus-4-7:Claude Code