Part 1 is pretty ugly, but fast. Part 2 is slower than I'd like (~200ms in Release) so I may revisit, but it's fast enough for now. The slowest part seems to be FindIndex on the gap list.