List<Widget> _mergeInlineChildren(_InlineElement inline)
            {
                List<Widget> mergedTexts = new List<Widget>();
                foreach (Widget child in inline.children)
                {
                    var childText = child as RichText;
                    if (mergedTexts.isNotEmpty() && mergedTexts.last() is RichText && childText != null)
                    {
                        RichText previous = (RichText) mergedTexts.removeLast();
                        List<TextSpan> children =
                            previous.text.children != null
                                ? previous.text.children
                                : new List<TextSpan>() {previous.text};
                        children.Add(childText.text);
                        TextSpan mergeSpan = new TextSpan("", null, children);
                        mergedTexts.Add(new RichText(text:mergeSpan));
                    }
                    else
                    {
                        mergedTexts.Add(child);
                    }
                }

                return mergedTexts;
            }
            void _addAnonymousBLockIfNeeded(TextStyle style)
            {
                if (_inlines.isEmpty())
                {
                    return;
                }

                _InlineElement inline = _inlines.Single();
                if (inline.children.isNotEmpty())
                {
                    List<Widget> mergedInlines = _mergeInlineChildren(inline);
                    Wrap wrap = new Wrap(null, Axis.horizontal, WrapAlignment.start, 0, WrapAlignment.start, 0,
                        WrapCrossAlignment.start, null, VerticalDirection.down, mergedInlines);
                    _addBlockChild(wrap);
                    _inlines.Clear();
                }
            }
            public override void visitElementAfter(markdown.Element element)
            {
                string tag = element.tag;
                if (_isBlockTag(tag))
                {
                    _addAnonymousBLockIfNeeded(styleSheet.styles(tag));

                    _BlockElement current = _blocks.removeLast();
                    Widget child;

                    if (current.children.isNotEmpty())
                    {
                        child = new Column(null, null, null, MainAxisAlignment.start, MainAxisSize.max,
                            CrossAxisAlignment.stretch, VerticalDirection.down, current.children);
                    }
                    else
                    {
                        child = new SizedBox();
                    }

                    if (_isListTag(tag))
                    {
                        Debug.Assert(_listIndents.isNotEmpty(), "_listIndents.isNotEmpty()");
                        _listIndents.removeLast();
                    }
                    else if (tag == "li")
                    {
                        if (_listIndents.isNotEmpty())
                        {
                            child = new Row(
                                null,
                                null,
                                null,
                                MainAxisAlignment.start,
                                MainAxisSize.max,
                                CrossAxisAlignment.start,
                                VerticalDirection.down,
                                new List<Widget>()
                                {
                                    new SizedBox(null, styleSheet.listIndent, null, _buildBullet(_listIndents.last())),
                                    new Expanded(null, 1, child)
                                });
                        }
                    }
                    else if (tag == "blockquote")
                    {
                        child = new DecoratedBox(
                            null,
                            styleSheet.blockquoteDecoration,
                            DecorationPosition.background,
                            new Padding(
                                null,
                                EdgeInsets.all(styleSheet.blockquotePadding),
                                child));
                    }
                    else if (tag == "pre")
                    {
                        child = new DecoratedBox(
                            null,
                            styleSheet.codeblockDecoration,
                            DecorationPosition.background,
                            new Padding(
                                null,
                                EdgeInsets.all(styleSheet.codeblockPadding),
                                child));
                    }
                    else if (tag == "hr")
                    {
                        child = new DecoratedBox(
                            null,
                            styleSheet.horizontalRuleDecoration,
                            DecorationPosition.background,
                            child);
                    }

                    _addBlockChild(child);
                }
                else
                {
                    _InlineElement current = _inlines.removeLast();
                    _InlineElement parent = _inlines.last();

                    if (tag == "img")
                    {
                        current.children.Add(_buildImage(element.attributes["src"]));
                    }
                    else if (tag == "a")
                    {
                        _linkHandlers.removeLast();
                    }

                    if (current.children.isNotEmpty())
                    {
                        parent.children.AddRange(current.children);
                    }
                }
            }