public static object BuildContentForRun(IDataModel model, int source, int destination, IFormattedRun destinationRun, int preferredPaletteStart = -1, int preferredSpritePage = 0)
 {
     if (destination != destinationRun.Start)
     {
         return(null);
     }
     if (destinationRun is PCSRun pcs)
     {
         return(PCSString.Convert(model, pcs.Start, pcs.Length));
     }
     else if (destinationRun is ISpriteRun sprite)
     {
         if (sprite is LzTilemapRun tilemap)
         {
             tilemap.FindMatchingTileset(model);
         }
         var paletteRuns = sprite.FindRelatedPalettes(model, source);
         var paletteRun  = paletteRuns.FirstOrDefault();
         if (preferredPaletteStart >= 0)
         {
             paletteRun = paletteRuns.FirstOrDefault(pRun => pRun.Start == preferredPaletteStart) ?? model.GetNextRun(preferredPaletteStart) as IPaletteRun;
         }
         var pixels = sprite.GetPixels(model, preferredSpritePage);
         if (pixels == null)
         {
             return(null);
         }
         var colors    = paletteRun?.AllColors(model) ?? TileViewModel.CreateDefaultPalette((int)Math.Pow(2, sprite.SpriteFormat.BitsPerPixel));
         var imageData = SpriteTool.Render(pixels, colors, paletteRun?.PaletteFormat.InitialBlankPages ?? 0, 0);
         return(new ReadonlyPixelViewModel(sprite.SpriteFormat, imageData));
     }
     else if (destinationRun is IPaletteRun paletteRun)
     {
         var colors = paletteRun.GetPalette(model, 0);
         return(new ReadonlyPaletteCollection(colors));
     }
     else if (destinationRun is IStreamRun streamRun)
     {
         using (ModelCacheScope.CreateScope(model)) {
             var lines = streamRun.SerializeRun().Split(Environment.NewLine);
             if (lines.Length > 20)
             {
                 lines = lines.Take(20).ToArray();
             }
             return(Environment.NewLine.Join(lines));
         }
     }
     else if (destinationRun is ArrayRun arrayRun)
     {
         var stream = new StringBuilder();
         arrayRun.AppendTo(model, stream, arrayRun.Start, arrayRun.ElementLength * Math.Min(20, arrayRun.ElementCount), false);
         return(stream.ToString());
     }
     else
     {
         return(null);
     }
 }
        // TODO do some sort of caching: rendering these images every time probably sucks for performance.
        public IEnumerable <ComboOption> GetComboOptions(IDataModel model)
        {
            var defaultOptions = GetOptions(model)
                                 .Select((option, i) => new ComboOption(option, i))
                                 .Where(combo => combo.Text != null)
                                 .ToList();

            if (!(model.GetNextRun(model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, EnumName)) is ITableRun tableRun))
            {
                return(defaultOptions);
            }
            if (!(tableRun.ElementContent[0] is ArrayRunPointerSegment pointerSegment))
            {
                return(defaultOptions);
            }
            if (!LzSpriteRun.TryParseSpriteFormat(pointerSegment.InnerFormat, out var _) && !SpriteRun.TryParseSpriteFormat(pointerSegment.InnerFormat, out var _))
            {
                return(defaultOptions);
            }

            var imageOptions = new List <ComboOption>();

            for (int i = 0; i < tableRun.ElementCount; i++)
            {
                var destination = model.ReadPointer(tableRun.Start + tableRun.ElementLength * i);
                if (!(model.GetNextRun(destination) is ISpriteRun run))
                {
                    return(defaultOptions);
                }
                var sprite         = run.GetPixels(model, 0);
                var paletteAddress = SpriteTool.FindMatchingPalette(model, run, 0);
                var paletteRun     = model.GetNextRun(paletteAddress) as IPaletteRun;
                var palette        = paletteRun?.GetPalette(model, paletteRun.PaletteFormat.InitialBlankPages) ?? TileViewModel.CreateDefaultPalette(16);
                var image          = SpriteTool.Render(sprite, palette, paletteRun?.PaletteFormat.InitialBlankPages ?? default, 0);
                var option         = VisualComboOption.CreateFromSprite(defaultOptions[i].Text, image, sprite.GetLength(0), i);
                imageOptions.Add(option);
            }

            return(imageOptions);
        }