public static async Task <CustomTextSource4> UpdateFormattedText(ICodeView iface1)
        {
            Debug.WriteLine("Enteirng updateformattedtext " + iface1.PerformingUpdate);
            if (iface1.PerformingUpdate)
            {
                Debug.WriteLine("Already performing update");
                return(null);
            }

            iface1.PerformingUpdate = true;
            iface1.Status           = CodeControlStatus.Rendering;
            iface1.RaiseEvent(new RoutedEventArgs(RoslynCodeControl.RenderStartEvent, iface1));

            var textStorePosition = 0;
            var linePosition      = new Point(iface1.XOffset, 0);

            iface1.TextDestination.Children.Clear();

            var line = 0;

            Debug.WriteLine("Calling inner update");
            // ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
            var fontFamilyFamilyName = iface1.FontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")];

            Debug.WriteLine(fontFamilyFamilyName);
            Debug.WriteLine("OutputWidth " + iface1.OutputWidth);
            // not sure what to do here !!
            // Rectangle.Width = OutputWidth + Rectangle.StrokeThickness * 2;
            var emSize     = iface1.FontSize;
            var fontWeight = iface1.FontWeight;
            var customTextSource4Parameters = iface1.CreateDefaultTextSourceArguments();
            var mainUpdateParameters        = new MainUpdateParameters(textStorePosition, line, linePosition,
                                                                       RoslynCodeControl.Formatter, iface1.OutputWidth, iface1.PixelsPerDip, emSize, fontFamilyFamilyName,
                                                                       iface1.UpdateChannel.Writer, fontWeight, iface1.DocumentPaginator, customTextSource4Parameters);
            await iface1.JTF2.SwitchToMainThreadAsync();

            var source = await iface1.InnerUpdateAsync(mainUpdateParameters, customTextSource4Parameters);

            return(source);
        }
        /// <inheritdoc />
        public async Task UpdateFormattedTextAsync()
        {
            var codeView = (ICodeView)this;

            _debugFn?.Invoke($"Entering {nameof(UpdateFormattedTextAsync)} {codeView.PerformingUpdate}");
            if (codeView.PerformingUpdate)
            {
                _debugFn?.Invoke("Already performing update");
            }
            else
            {
                JTF.RunAsync(ReaderListenerAsync);

                codeView.PerformingUpdate = true;
                codeView.Status           = CodeControlStatus.Rendering;
                codeView.Reset();
                codeView.RaiseEvent(new RoutedEventArgs(RenderStartEvent, this));


                var text = await SyntaxTree.GetTextAsync();

                var o = new Point(double.NaN, 0);
                for (var i = 0; i < text.Lines.Count; i++)
                {
                    DrawLineNumber(i, o);
                    o.Y += LineHeight;
                }

                var textStorePosition = 0;
                var linePosition      = new Point(codeView.XOffset, 0);

                codeView.TextDestination.Children.Clear();

                var line = 0;

                _debugFn?.Invoke("Calling inner update");
                // ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
                var fontFamilyFamilyName = codeView.FontFamily.FamilyNames[XmlLanguage.GetLanguage("en-US")];
                _debugFn?.Invoke(fontFamilyFamilyName);
                _debugFn?.Invoke("OutputWidth " + codeView.OutputWidth);
                // not sure what to do here !!
                // Rectangle.Width = OutputWidth + Rectangle.StrokeThickness * 2;
                var emSize     = codeView.FontSize;
                var fontWeight = codeView.FontWeight;
                var customTextSource4Parameters = codeView.CreateDefaultTextSourceArguments();
                var mainUpdateParameters        = new MainUpdateParameters(textStorePosition, line, linePosition,
                                                                           CommonText.Formatter, codeView.OutputWidth, codeView.PixelsPerDip, emSize,
                                                                           fontFamilyFamilyName, codeView.UpdateChannel.Writer, fontWeight,
                                                                           null, customTextSource4Parameters, _debugFn);

                await JTF2.SwitchToMainThreadAsync();

                SecondaryThreadTasks();
                var source = codeView.InnerUpdate(mainUpdateParameters, customTextSource4Parameters);
                await JTF.SwitchToMainThreadAsync();

                codeView.CustomTextSource = source;
                _debugFn?.Invoke("Return from await inner update");

                codeView.PerformingUpdate = false;
                codeView.InitialUpdate    = false;
                codeView.RaiseEvent(new RoutedEventArgs(RenderCompleteEvent, this));
                codeView.Status            = CodeControlStatus.Rendered;
                codeView.InsertionPoint    = 0;
                codeView.InsertionLineNode = codeView.FindLine(0);
#if false
                foreach (var x1 in codeView.FindLine(0).List)
                {
                    for (var ci1 = x1.FirstCharInfo; ci1 != null && ci1.Value.Index < x1.Offset + x1.Length; ci1 =
                             ci1.Next)
                    {
                        Debug.WriteLine($"{x1.LineNumber:D4},{ci1.Value.LineIndex:D3},{ci1.Value.Index:D6}");
                    }
                }
#endif

#if false
                var #if av = codeView.FindLine(0).Value.FirstCharInfo.List.Average(c => c.AdvanceWidth);
                foreach (var x1 in codeView.FindLine(0).Value.FirstCharInfo.List.GroupBy(c => c.AdvanceWidth)
                         .Select(z => new { Width = z.Key, Count = z.Count() }))
                {
                    var msg = $"{x1.Width} - {x1.Count}";
                    DebugFn(msg);
                    Debug.WriteLine(msg);
                }
                Debug.WriteLine($"Average related to font size is {av/FontSize}");
#endif
                await UpdateRoslynPropertiesAsync();

                ScrollViewer.InvalidateScrollInfo();
            }
        }
        public static unsafe CustomTextSource4 InnerUpdateAsync(MainUpdateParameters mainUpdateParameters,
                                                                Func <CustomTextSource4> makeSource)
        {
            LinkedListNode <CharInfo> charInfoNode = null;
            const int batchLines = 100;
            var       lineInfos0 = new LineInfo2[batchLines];
            var       lineInfos1 = new LineInfo2[batchLines];
            var       lineInfos  = lineInfos0;
            int       @switch    = 0;

            mainUpdateParameters.DebugFn?.Invoke($"{nameof(InnerUpdateAsync)}", 5);
            var tf = CreateTypeface(new FontFamily(mainUpdateParameters.FaceName), FontStyles.Normal,

                                    FontStretches.Normal,
                                    mainUpdateParameters.FontWeight);

            var currentRendering = FontRendering.CreateInstance(mainUpdateParameters.FontSize,
                                                                TextAlignment.Left,
                                                                null,
                                                                Brushes.Black,
                                                                tf);

            var customTextSource4 = makeSource();

            var myGroup = new DrawingGroup();
            var myDc    = myGroup.Open();

            var genericTextParagraphProperties =
                new GenericTextParagraphProperties(currentRendering, mainUpdateParameters.PixelsPerDip);
            var runsInfos         = new List <TextRunInfo>();
            var allCharInfos      = new LinkedList <CharInfo>();
            var textStorePosition = mainUpdateParameters.TextStorePosition;
            var lineNo            = mainUpdateParameters.LineNo;
            // var tasks = new List<Task>();
            var linePosition = mainUpdateParameters.LinePosition;
            var liIndex      = 0;

            while (textStorePosition < customTextSource4.Length)
            {
                var runCount = customTextSource4.Runs.Count;
#if DEBUGTEXTSOURCE
                Debug.WriteLine("Runcount = " + runCount);
#endif
                var numPages  = 0;
                var pageBegin = new Point(0, 0);
                var pageEnd   = new Point(0, 0);
                if (mainUpdateParameters.Paginate)
                {
                    // ReSharper disable once PossibleInvalidOperationException
                    pageEnd.Offset(mainUpdateParameters.PageSize.Value.Width,
                                   mainUpdateParameters.PageSize.Value.Height);
                }

                LineInfo2 lineInfo;
                var       linePositionX = mainUpdateParameters.ParagraphWidth - linePosition.X;
                if (linePositionX < 0)
                {
                    linePositionX = 0;
                }
                using (var myTextLine = mainUpdateParameters.TextFormatter.FormatLine(customTextSource4,
                                                                                      textStorePosition, linePositionX,
                                                                                      genericTextParagraphProperties,
                                                                                      null))
                {
                    var nRuns = customTextSource4.Runs.Count - runCount;
                    if (nRuns < 0)
                    {
                        throw new InvalidOperationException("NRuns is negative" + nRuns);
                    }
#if DEBUGTEXTSOURCE
                    Debug.WriteLine("num runs for line is " + nRuns);
#endif

                    var curCharInfoNode = charInfoNode;
                    HandleLine(allCharInfos, linePosition, myTextLine, customTextSource4, runCount,
                               nRuns, lineNo, textStorePosition, runsInfos, curCharInfoNode, out charInfoNode,
                               mainUpdateParameters.DebugFn);
                    myTextLine.Draw(myDc, linePosition, InvertAxes.None);

                    lineInfos[liIndex++] = new LineInfo2(lineNo, curCharInfoNode != null? curCharInfoNode.Next : allCharInfos.First, textStorePosition, linePosition, myTextLine.Height,
                                                         myTextLine.Length);
                    linePosition.Y += myTextLine.Height;
                    lineNo++;

                    // Update the index position in the text store.
                    textStorePosition += myTextLine.Length;
                    if (mainUpdateParameters.Paginate && linePosition.Y >= pageEnd.Y)
                    {
                        Debug.WriteLine($"numPages: {numPages}");
                        numPages++;
                    }
                }

#if GROUPEDDG
                if (lineNo > 0 && lineNo % batchLines == 0)
                {
                    myDc.Close();
                    myGroup.Freeze();
                    var curUi = new UpdateInfo()
                    {
                        DrawingGroup = myGroup, CharInfos = allCharInfos.ToList <CharInfo>()
                    };
                    await mainUpdateParameters.ChannelWriter.WriteAsync(curUi);

                    // tasks.Add(writeAsync.AsTask());
                    myGroup = new DrawingGroup();
                    myDc    = myGroup.Open();
                }
#else
                if (lineNo <= 0 || lineNo % batchLines != 0)
                {
                    continue;
                }
                myDc.Close();
                myGroup.Freeze();
                var curUi = new UpdateInfo(
                    myGroup,
                    liIndex,
                    lineInfos
                    );
                liIndex = 0;
                if (@switch == 0)
                {
                    lineInfos = lineInfos1;
                    @switch   = 1;
                }
                else
                {
                    lineInfos = lineInfos0;
                    @switch   = 0;
                }
                mainUpdateParameters.ChannelWriter.WriteAsync(curUi);
                myGroup = new DrawingGroup();
                myDc    = myGroup.Open();
#endif
            }

            customTextSource4.RunInfos = runsInfos;
#if GROUPEDDG
            if (lineNo % 100 != 0)
            {
                myDc.Close();
                myGroup.Freeze();
                var curUi = new UpdateInfo()
                {
                    DrawingGroup = myGroup, CharInfos = Enumerable.ToList <CharInfo>(allCharInfos), FinalBlock = true
                };
                await mainUpdateParameters.ChannelWriter.WriteAsync(curUi);

                // tasks.Add(writeAsync.AsTask());
            }
            else
            {
                myDc.Close();
            }
#else
            if (lineNo % batchLines == 0)
            {
                return(customTextSource4);
            }
            {
                myDc.Close();
                myGroup.Freeze();
                var curUi = new UpdateInfo(
                    myGroup,
                    liIndex,
                    lineInfos
                    );
                mainUpdateParameters.ChannelWriter.WriteAsync(curUi);
            }
#endif
            // await Task.WhenAll(tasks);

            return(customTextSource4);
        }
 /// <inheritdoc />
 public CustomTextSource4 InnerUpdate(MainUpdateParameters mainUpdateParameters,
                                      TextSourceInitializationParameters textSourceInitializationParameters)
 {
     return(CommonText.InnerUpdateAsync(mainUpdateParameters,
                                        () => CreateCustomTextSource4(textSourceInitializationParameters)));
 }