private void ProcessImage(CommentImage image, string imageUrl, string originalUrl, ITextViewLine line, int lineNumber, SnapshotSpan span, double scale, string filepath)
        {
            try
            {
                var result = image.TrySet(
                    imageUrl,
                    originalUrl,
                    scale,
                    filepath,
                    out Exception imageLoadingException);

                // Position image and add as adornment
                if (imageLoadingException == null)
                {
                    AddComment(image, line, lineNumber, span);
                }
                else
                {
                    Images.TryRemove(lineNumber, out var commentImage);
                    commentImage.Dispose();

                    m_errorTags.Add(
                        new TagSpan <ErrorTag>(
                            span,
                            new ErrorTag("Trouble loading image", GetErrorMessage(imageLoadingException))));
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler.Notify(ex, true);
            }
        }
        private void CreateVisuals(ITextViewLine line, int lineNumber, string filepath)     // #eiichi CreateVisuals
        {
            // #hang_no 4
            try
            {
                // #eiichi start
                if (RichTextBoxs.ContainsKey(lineNumber))
                {   // BookMarkがある
                    var start = line.Extent.Start.Position + 0;
                    int len   = line.Extent.Length - 1;
                    if (len <= 0)
                    {
                        len = 1;
                    }
                    ;
                    var end  = line.Start + len;
                    var span = new SnapshotSpan(m_view.TextSnapshot, Span.FromBounds(start, end));

                    CommentRichTextBox TextBox = RichTextBoxs[lineNumber];
                    AddComment(TextBox, line, lineNumber, span);
                }
                else
                {
                    var lineText = line.Extent.GetText();
                    var lines    = lineText.Split(
                        new string[] { Environment.NewLine },
                        StringSplitOptions.RemoveEmptyEntries);
                    // multiline mean a block of code is collapsed
                    // do not display pics from the collapsed text
                    if (lines.Length > 1)
                    {
                        return;
                    }
                    var matchIndex = CommentImageParser.Match(m_contentTypeName, lineText, out string matchedText);
                    if (matchIndex >= 0)
                    {
                        // Get coordinates of text
                        var start = line.Extent.Start.Position + matchIndex;
                        var end   = line.Start + (line.Extent.Length - 1);
                        var span  = new SnapshotSpan(m_view.TextSnapshot, Span.FromBounds(start, end));

                        CommentImageParser.TryParse(
                            matchedText,
                            out string imageUrl, out double scale, out Exception xmlParseException);

                        if (xmlParseException != null)
                        {
                            CommentImage commentImage;
                            if (Images.TryRemove(lineNumber, out commentImage))
                            {
                                m_layer.RemoveAdornment(commentImage);
                                commentImage.Dispose();
                            }

                            m_errorTags.Add(
                                new TagSpan <ErrorTag>(
                                    span,
                                    new ErrorTag("XML parse error", GetErrorMessage(xmlParseException))));

                            return;
                        }

                        var          reload = false;
                        CommentImage image  = Images.AddOrUpdate(lineNumber, ln =>
                        {
                            reload = true;
                            return(new CommentImage(m_Util));
                        }, (ln, img) =>
                        {
                            if (img.OriginalUrl == imageUrl && img.Scale != scale)
                            {
                                // URL same but scale changed
                                img.Scale = scale;
                                reload    = true;
                            }
                            else if (img.OriginalUrl != imageUrl)
                            {
                                // URL different, must load from new source
                                reload = true;
                            }
                            return(img);
                        });

                        var originalUrl = imageUrl;
                        if (reload)
                        {
                            if (m_processingUris.Contains(imageUrl))
                            {
                                return;
                            }

                            if (imageUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                            {
                                if (ImageCache.Instance.TryGetValue(imageUrl, out string localPath))
                                {
                                    imageUrl = localPath;
                                }
                                else
                                {
                                    m_processingUris.Add(imageUrl);
                                    var       tempPath = Path.Combine(Path.GetTempPath(), Path.GetFileName(imageUrl));
                                    WebClient client   = new WebClient();
                                    client.DownloadDataCompleted += Client_DownloadDataCompleted;

                                    m_toaddImages.TryAdd(
                                        client,
                                        new ImageParameters()
                                    {
                                        Uri        = imageUrl,
                                        LocalPath  = tempPath,
                                        Image      = image,
                                        Line       = line,
                                        LineNumber = lineNumber,
                                        Span       = span,
                                        Scale      = scale,
                                        Filepath   = filepath
                                    });

                                    client.DownloadDataAsync(new Uri(imageUrl));

                                    return;
                                }
                            }
                        }

                        if (imageUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                        {
                            if (ImageCache.Instance.TryGetValue(imageUrl, out string localPath))
                            {
                                imageUrl = localPath;
                            }
                        }
                        ProcessImage(image, imageUrl, originalUrl, line, lineNumber, span, scale, filepath);        // #Image ProcessImage
                    }
                    else
                    {
                        Images.TryRemove(lineNumber, out var commentImage);
                        if (commentImage != null)           // #hang_this これ入れないとハングする
                        {
                            commentImage.Dispose();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHandler.Notify(ex, true);
            }
        }