void DrawMessageExtendIcon(Mono.TextEditor.TextEditor editor, Cairo.Context g, double y, int errorCounterWidth, int eh)
        {
            EnsureLayoutCreated(editor);
            double rW = errorCounterWidth - 2;
            double rH = editor.LineHeight * 3 / 4;

            double rX = editor.Allocation.Width - rW - 2;
            double rY = y + (editor.LineHeight - rH) / 2;

            BookmarkMarker.DrawRoundRectangle(g, rX, rY, 8, rW, rH);

            g.Color = oldIsOver ? new Cairo.Color(0.3, 0.3, 0.3) : new Cairo.Color(0.5, 0.5, 0.5);
            g.Fill();
            if (CollapseExtendedErrors)
            {
                if (errorCountLayout != null)
                {
                    g.Color = cache.gcLight;
                    g.Save();
                    g.Translate(rX + rW / 4, rY + (rH - eh) / 2);
                    g.ShowLayout(errorCountLayout);
                    g.Restore();
                }
                else
                {
                    g.MoveTo(rX + rW / 2 - rW / 4, rY + rH / 4);
                    g.LineTo(rX + rW / 2 + rW / 4, rY + rH / 4);
                    g.LineTo(rX + rW / 2, rY + rH - rH / 4);
                    g.ClosePath();

                    g.Color = new Cairo.Color(1, 1, 1);
                    g.Fill();
                }
            }
            else
            {
                g.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4);
                g.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4);
                g.LineTo(rX + rW / 2, rY + rH / 4);
                g.ClosePath();

                g.Color = new Cairo.Color(1, 1, 1);
                g.Fill();
            }
        }
        protected override bool OnExposeEvent(Gdk.EventExpose evnt)
        {
            using (var cr = Gdk.CairoHelper.Create(evnt.Window)) {
                cr.SetSourceRGBA(1, 1, 1, 0);
                cr.Operator = Cairo.Operator.Source;
                cr.Paint();
            }

            using (var cr = Gdk.CairoHelper.Create(evnt.Window)) {
                cr.Translate(width / 2, height / 2);
                cr.Scale(1 + scale / 8, 1 + scale / 8);
                int x = -(marker.ErrorTextBounds.Width) / 2;
                int y = -marker.ErrorTextBounds.Height / 2;

                if (marker.FitsInSameLine)
                {
                    cr.MoveTo(x + Editor.LineHeight / 2, y);
                    cr.LineTo(x, 0);
                    cr.LineTo(x + Editor.LineHeight / 2, marker.ErrorTextBounds.Height / 2);
                }
                else
                {
                    cr.MoveTo(x, -marker.ErrorTextBounds.Height / 2);
                    cr.LineTo(x, marker.ErrorTextBounds.Height / 2);
                }
                cr.LineTo(x + marker.ErrorTextBounds.Width, marker.ErrorTextBounds.Height / 2);
                cr.LineTo(x + marker.ErrorTextBounds.Width, y);
                cr.ClosePath();

                Mono.TextEditor.HslColor hsl = marker.colorMatrix [0, 0, 0, 0, 0];
                double delta = 1 + 2 - scale;
                hsl.S += delta;
                var color = (Cairo.Color)hsl;
                color.A  = opacity;
                cr.Color = color;
                cr.FillPreserve();
                color    = marker.colorMatrix [0, 0, 2, 0, 0];
                color.A  = opacity;
                cr.Color = color;
                cr.Stroke();
                int errorCounterWidth = 0;

                if (marker.Errors.Count > 1)
                {
                    double rY = y + Editor.LineHeight / 6;
                    int    ew, eh;
                    marker.errorCountLayout.GetPixelSize(out ew, out eh);
                    errorCounterWidth = ew + 10;
                    int rX = x + marker.ErrorTextBounds.Width - errorCounterWidth;

                    int    rW = errorCounterWidth - 2;
                    double rH = Editor.LineHeight * 3 / 4;

                    BookmarkMarker.DrawRoundRectangle(cr, rX, rY, 8, rW, rH);
                    cr.Color = new Cairo.Color(0.5, 0.5, 0.5);
                    cr.Fill();

                    cr.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4);
                    cr.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4);
                    cr.LineTo(rX + rW / 2, rY + rH / 4);
                    cr.ClosePath();

                    cr.Color = new Cairo.Color(1, 1, 1);
                    cr.Fill();
                }

                cr.Color = new Cairo.Color(0, 0, 0);
                marker.EnsureLayoutCreated(base.Editor);

                int layoutWidth, layoutHeight;
                marker.Layouts [0].Layout.GetPixelSize(out layoutWidth, out layoutHeight);
                double ly;
                if (marker.CollapseExtendedErrors || marker.Errors.Count == 1)
                {
                    ly = 1 + y + (marker.ErrorTextBounds.Height - layoutHeight) / 2;
                    double x2 = x + MessageBubbleTextMarker.border;
                    if (marker.FitsInSameLine)
                    {
                        x2 += 1 + Editor.LineHeight / 2;
                    }
                    cr.Translate(x2, ly);
                    cr.ShowLayout(marker.Layouts [0].Layout);
                }
                else
                {
                    ly = 1 + y + (Editor.LineHeight - layoutHeight) / 2;
                    for (int i = 0; i < marker.Errors.Count; i++)
                    {
                        marker.Layouts [i].Layout.GetPixelSize(out layoutWidth, out layoutHeight);
                        cr.Save();
                        double x2;
                        if (i == 0)
                        {
                            x2 = x + marker.ErrorTextBounds.Width - layoutWidth - errorCounterWidth;
                        }
                        else
                        {
                            x2 = x + MessageBubbleTextMarker.border;
                        }
                        if (marker.FitsInSameLine)
                        {
                            x2 += Editor.LineHeight / 2;
                        }
                        cr.Translate(x2, ly);
                        cr.ShowLayout(marker.Layouts [i].Layout);
                        cr.Restore();
                        ly += Editor.LineHeight;
                    }
                }
            }
            return(false);
        }
        public bool DrawBackground(TextEditor editor, Cairo.Context g, TextViewMargin.LayoutWrapper layout2, int selectionStart, int selectionEnd, int startOffset, int endOffset, double y, double startXPos, double endXPos, ref bool drawBg)
        {
            if (!IsVisible || DebuggingService.IsDebugging)
            {
                return(true);
            }
            EnsureLayoutCreated(editor);
            double x = editor.TextViewMargin.XOffset;
            int    right = editor.Allocation.Width;
            int    errorCounterWidth = 0;
            bool   isCaretInLine = startOffset <= editor.Caret.Offset && editor.Caret.Offset <= endOffset;
            int    ew = 0, eh = 0;

            if (errors.Count > 1 && errorCountLayout != null)
            {
                errorCountLayout.GetPixelSize(out ew, out eh);
                errorCounterWidth = ew + 10;
            }

            double x2            = System.Math.Max(right - LayoutWidth - border - (ShowIconsInBubble ? errorPixbuf.Width : 0) - errorCounterWidth, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset);
            bool   isEolSelected = editor.IsSomethingSelected && editor.SelectionMode != SelectionMode.Block ? editor.SelectionRange.Contains(lineSegment.Offset + lineSegment.EditableLength) : false;

            int active      = editor.Document.GetTextAt(lineSegment) == initialText ? 0 : 1;
            int highlighted = active == 0 && isCaretInLine ? 1 : 0;
            int selected    = 0;

            double topSize    = Math.Floor(editor.LineHeight / 2);
            double bottomSize = editor.LineHeight / 2 + editor.LineHeight % 2;

            if (!fitsInSameLine)
            {
                if (isEolSelected)
                {
                    x -= (int)editor.HAdjustment.Value;
                    editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, editor.TextViewMargin.TextStartPosition, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true);
                    editor.TextViewMargin.DrawRectangleWithRuler(g, x + editor.TextViewMargin.TextStartPosition, new Cairo.Rectangle(x + editor.TextViewMargin.TextStartPosition, y + editor.LineHeight, editor.Allocation.Width + (int)editor.HAdjustment.Value, editor.LineHeight), editor.ColorStyle.Selection.CairoBackgroundColor, true);
                    x += (int)editor.HAdjustment.Value;
                }
                else
                {
                    editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y + editor.LineHeight, x2, editor.LineHeight), editor.ColorStyle.Default.CairoBackgroundColor, true);
                }
            }
            DrawRectangle(g, x, y, right, topSize);
            g.Color = colorMatrix [active, TOP, LIGHT, highlighted, selected];
            g.Fill();
            DrawRectangle(g, x, y + topSize, right, bottomSize);
            g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected];
            g.Fill();

            g.MoveTo(new Cairo.PointD(x, y + 0.5));
            g.LineTo(new Cairo.PointD(x + right, y + 0.5));
            g.Color = colorMatrix [active, TOP, LINE, highlighted, selected];
            g.Stroke();

            g.MoveTo(new Cairo.PointD(x, y + editor.LineHeight - 0.5));
            g.LineTo(new Cairo.PointD((fitsInSameLine ? x + right : x2 + 1), y + editor.LineHeight - 0.5));
            g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
            g.Stroke();
            if (editor.Options.ShowRuler)
            {
                double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX);
                g.MoveTo(new Cairo.PointD(divider + 0.5, y));
                g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight));
                g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
                g.Stroke();
            }

// draw background
            if (layout2.StartSet || selectionStart == endOffset)
            {
                double startX;
                double endX;

                if (selectionStart != endOffset)
                {
                    var start = layout2.Layout.IndexToPos((int)layout2.SelectionStartIndex);
                    startX = (int)(start.X / Pango.Scale.PangoScale);
                    var end = layout2.Layout.IndexToPos((int)layout2.SelectionEndIndex);
                    endX = (int)(end.X / Pango.Scale.PangoScale);
                }
                else
                {
                    startX = x2;
                    endX   = startX;
                }

                if (editor.MainSelection.SelectionMode == SelectionMode.Block && startX == endX)
                {
                    endX = startX + 2;
                }
                startX += startXPos;
                endX   += startXPos;
                startX  = Math.Max(editor.TextViewMargin.XOffset, startX);
// clip region to textviewmargin start
                if (isEolSelected)
                {
                    endX = editor.Allocation.Width + (int)editor.HAdjustment.Value;
                }
                if (startX < endX)
                {
                    DrawRectangle(g, startX, y, endX - startX, topSize);
                    g.Color = colorMatrix [active, TOP, LIGHT, highlighted, 1];
                    g.Fill();
                    DrawRectangle(g, startX, y + topSize, endX - startX, bottomSize);
                    g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1];
                    g.Fill();

                    g.MoveTo(new Cairo.PointD(startX, y + 0.5));
                    g.LineTo(new Cairo.PointD(endX, y + 0.5));
                    g.Color = colorMatrix [active, TOP, LINE, highlighted, 1];
                    g.Stroke();

                    if (startX < x2)
                    {
                        g.MoveTo(new Cairo.PointD(startX, y + editor.LineHeight - 0.5));
                        g.LineTo(new Cairo.PointD(System.Math.Min(endX, x2 + 1), y + editor.LineHeight - 0.5));
                        g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1];
                        g.Stroke();
                        if (x2 + 1 < endX)
                        {
                            g.MoveTo(new Cairo.PointD(x2 + 1, y + editor.LineHeight - 0.5));
                            g.LineTo(new Cairo.PointD(endX, y + editor.LineHeight - 0.5));
                            g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, 1];
                            g.Stroke();
                        }
                    }

                    if (editor.Options.ShowRuler)
                    {
                        double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX);
                        g.MoveTo(new Cairo.PointD(divider + 0.5, y));
                        g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight));
                        g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, 1];
                        g.Stroke();
                    }
                }
            }

            if (!fitsInSameLine)
            {
                y += editor.LineHeight;
            }
            double y2       = y + 0.5;
            double y2Bottom = y2 + editor.LineHeight - 1;

            selected = isEolSelected && (CollapseExtendedErrors || errors.Count == 1) ? 1 : 0;

// draw message text background
            if (CollapseExtendedErrors || errors.Count == 1)
            {
                if (!fitsInSameLine)
                {
// draw box below line
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2 - 1));
                    g.ClosePath();
                    g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected];
                    g.Fill();

                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
                    g.Stroke();
                }
                else
                {
// draw 'arrow marker' in the same line
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2));
                    double mid = y2 + topSize;
                    g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid));

                    g.LineTo(new Cairo.PointD(right, mid));
                    g.LineTo(new Cairo.PointD(right, y2));
                    g.ClosePath();
                    g.Color = colorMatrix [active, TOP, DARK, highlighted, selected];
                    g.Fill();
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, mid));

                    g.LineTo(new Cairo.PointD(right, mid));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.ClosePath();

                    g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected];
                    g.Fill();

// draw border
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2));
                    g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2));

                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2));
                    g.ClosePath();

                    g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
                    g.Stroke();
                }
            }
            else
            {
                if (!fitsInSameLine)
                {
// draw box below line
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2 - 1));
                    g.ClosePath();
                }
                else
                {
// draw filled arrow box
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2));
                    g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2Bottom));
                    g.LineTo(new Cairo.PointD(right, y2));
                    g.ClosePath();
                }
                g.Color = colorMatrix [active, BOTTOM, LIGHT, highlighted, selected];
                g.Fill();

// draw light bottom line
                g.MoveTo(new Cairo.PointD(right, y2Bottom));
                g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                g.Stroke();

// stroke left line
                if (fitsInSameLine)
                {
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2));
                    g.LineTo(new Cairo.PointD(x2 - editor.LineHeight / 2 + 0.5, y2 + editor.LineHeight / 2));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom));
                }
                else
                {
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y2 - 1));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2Bottom + 1));
                }

                g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
                g.Stroke();

// stroke top line
                if (fitsInSameLine)
                {
                    g.Color = colorMatrix [active, BOTTOM, LINE, highlighted, selected];
                    g.MoveTo(new Cairo.PointD(right, y2));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y2));
                    g.Stroke();
                }
            }

            if (editor.Options.ShowRuler)
            {
                double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX);
                if (divider >= x2)
                {
                    g.MoveTo(new Cairo.PointD(divider + 0.5, y2));
                    g.LineTo(new Cairo.PointD(divider + 0.5, y2Bottom));
                    g.Color = colorMatrix [active, BOTTOM, DARK, highlighted, selected];
                    g.Stroke();
                }
            }

            if (errors.Count > 1 && errorCountLayout != null)
            {
                double rX = x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth;
                double rY = y + editor.LineHeight / 6;
                double rW = errorCounterWidth - 2;
                double rH = editor.LineHeight * 3 / 4;
                BookmarkMarker.DrawRoundRectangle(g, rX, rY, 8, rW, rH);

                g.Color = oldIsOver ? new Cairo.Color(0.3, 0.3, 0.3) : new Cairo.Color(0.5, 0.5, 0.5);
                g.Fill();
                if (CollapseExtendedErrors)
                {
                    g.Color = gcLight;
                    g.Save();
                    g.Translate(x2 + (ShowIconsInBubble ? errorPixbuf.Width : 0) + border + LayoutWidth + 4, y + (editor.LineHeight - eh) / 2 + eh % 2);
                    g.ShowLayout(errorCountLayout);
                    g.Restore();
                }
                else
                {
                    g.MoveTo(rX + rW / 2 - rW / 4, rY + rH - rH / 4);
                    g.LineTo(rX + rW / 2 + rW / 4, rY + rH - rH / 4);
                    g.LineTo(rX + rW / 2, rY + rH / 4);
                    g.ClosePath();

                    g.Color = new Cairo.Color(1, 1, 1);
                    g.Fill();
                }
            }

            for (int i = 0; i < layouts.Count; i++)
            {
                LayoutDescriptor layout = layouts [i];
                x2 = right - layout.Width - border - errorPixbuf.Width;
                if (i == 0)
                {
                    x2 -= errorCounterWidth;
                }
                x2 = System.Math.Max(x2, fitsInSameLine ? editor.TextViewMargin.XOffset + editor.LineHeight / 2 : editor.TextViewMargin.XOffset);
                if (i > 0)
                {
                    editor.TextViewMargin.DrawRectangleWithRuler(g, x, new Cairo.Rectangle(x, y, right, editor.LineHeight), isEolSelected ? editor.ColorStyle.Selection.CairoBackgroundColor : editor.ColorStyle.Default.CairoBackgroundColor, true);
                    g.MoveTo(new Cairo.PointD(x2 + 0.5, y));
                    g.LineTo(new Cairo.PointD(x2 + 0.5, y + editor.LineHeight));
                    g.LineTo(new Cairo.PointD(right, y + editor.LineHeight));
                    g.LineTo(new Cairo.PointD(right, y));
                    g.ClosePath();

                    if (CollapseExtendedErrors)
                    {
                        using (var pat = new Cairo.LinearGradient(x2, y, x2, y + editor.LineHeight)) {
                            pat.AddColorStop(0, colorMatrix [active, TOP, LIGHT, highlighted, selected]);
                            pat.AddColorStop(1, colorMatrix [active, BOTTOM, LIGHT, highlighted, selected]);
                            g.Pattern = pat;
                        }
                    }
                    else
                    {
                        g.Color = colorMatrix[active, TOP, LIGHT, highlighted, selected];
                    }
                    g.Fill();
                    if (editor.Options.ShowRuler)
                    {
                        double divider = Math.Max(editor.TextViewMargin.XOffset, x + editor.TextViewMargin.RulerX);
                        if (divider >= x2)
                        {
                            g.MoveTo(new Cairo.PointD(divider + 0.5, y));
                            g.LineTo(new Cairo.PointD(divider + 0.5, y + editor.LineHeight));
                            g.Color = colorMatrix[active, BOTTOM, DARK, highlighted, selected];
                            g.Stroke();
                        }
                    }
                }
                int lw, lh;
                layout.Layout.GetPixelSize(out lw, out lh);
                g.Color = (HslColor)(selected == 0 ? gc : gcSelected);
                g.Save();
                g.Translate(x2 + errorPixbuf.Width + border, y + (editor.LineHeight - layout.Height) / 2 + layout.Height % 2);
                g.ShowLayout(layout.Layout);
                g.Restore();
                y += editor.LineHeight;
                if (!UseVirtualLines)
                {
                    break;
                }
            }
            return(true);
        }