public string Find(string name, bool searchInheritance = true)
        {
            string result = null;

            if (!map.TryGetValue(name, out result))
            {
                if (inherited != null && searchInheritance)
                {
                    return(inherited.Find(name, searchInheritance));
                }
            }
            return(result);
        }
        void WalkElements(XElement e, CssAttributes inherited)
        {
            double beforeSize = (inherited != null) ? inherited.GetFontSize() : 0;

            CssAttributes attrs = CssAttributes.Parse((string)e.Attribute("style"), inherited);
            double        size  = attrs.GetFontSize();

            if (ignoreFirstParagraph && e.Name.LocalName == "p")
            {
                // ignore first paragraph.
                ignoreFirstParagraph = false;
                return;
            }

            bool heading = false;

            if (beforeSize != size)
            {
                if (size == 12)
                {
                    writer.Write("### ");
                    heading = true;
                }
                else if (size >= 13 && size < 17 && beforeSize != 13)
                {
                    writer.Write("## ");
                    heading = true;
                }
                else if (size >= 17)
                {
                    writer.Write("# ");
                    heading = true;
                }
                else
                {
                    Console.WriteLine("Font size changed to {0} on element {1}", size, e.Name.LocalName);
                }
            }
            if (heading)
            {
                attrs.Push("heading", "true");
            }

            foreach (XNode child in e.Nodes())
            {
                if (child is XElement)
                {
                    XElement ce = (XElement)child;
                    switch (ce.Name.LocalName)
                    {
                    case "a":
                        writer.Write("[");
                        WalkElements(ce, attrs);
                        writer.Write("](");
                        WriteAnchor((string)ce.Attribute("href"), attrs);
                        writer.Write(")");
                        break;

                    case "h3":
                        CheckNewLine();
                        if (!string.IsNullOrWhiteSpace(ce.Value))
                        {
                            attrs.Push("font-size", "12pt");
                            attrs.Push("heading", "true");
                            writer.Write("### ");
                            WalkElements(ce, attrs);
                            attrs.Pop("font-size");
                            attrs.Pop("heading");
                            WriteLine();
                        }
                        break;

                    case "h2":
                        CheckNewLine();
                        if (!string.IsNullOrWhiteSpace(ce.Value))
                        {
                            attrs.Push("font-size", "13pt");
                            attrs.Push("heading", "true");
                            writer.Write("## ");
                            WalkElements(ce, attrs);
                            attrs.Pop("font-size");
                            attrs.Pop("heading");
                            WriteLine();
                        }
                        break;

                    case "h1":
                        CheckNewLine();
                        if (!string.IsNullOrWhiteSpace(ce.Value))
                        {
                            attrs.Push("font-size", "17pt");
                            attrs.Push("heading", "true");
                            writer.Write("# ");
                            WalkElements(ce, attrs);
                            attrs.Pop("font-size");
                            attrs.Pop("heading");
                            WriteLine();
                        }
                        break;

                    case "div":
                    case "p":
                        CheckNewLine();
                        WalkElements(ce, attrs);
                        WriteLine();
                        break;

                    case "li":
                        string listType = attrs.Find("list");
                        if (listType == "ordered")
                        {
                            writer.Write("1. ");
                        }
                        else
                        {
                            writer.Write("* ");
                        }
                        WalkElements(ce, attrs);
                        WriteLine();
                        break;

                    case "span":

                        if (!string.IsNullOrEmpty(ce.Value))
                        {
                            bool bold = attrs.Find("fond-weight") == "bold";
                            if (bold)
                            {
                                writer.Write("** ");
                            }
                            WalkElements(ce, attrs);
                            if (bold)
                            {
                                writer.Write("** ");
                            }
                        }
                        break;

                    case "img":
                        CheckNewLine();
                        writer.Write("![");
                        writer.Write("](");
                        WriteAnchor((string)ce.Attribute("src"), attrs);
                        writer.Write(")");
                        break;

                    case "ol":
                        CheckNewLine();
                        attrs.Push("list", "ordered");
                        WalkElements(ce, attrs);
                        attrs.Pop("list");
                        WriteLine();
                        break;

                    case "ul":
                        CheckNewLine();
                        attrs.Push("list", "unordered");
                        WalkElements(ce, attrs);
                        attrs.Pop("list");
                        WriteLine();
                        break;

                    case "br":
                        WriteLine();
                        break;

                    case "table":
                        throw new Exception("HTML Table doesn't translate to markdown");

                    default:
                        Console.WriteLine("Ignoring element: " + ce.Name.LocalName);
                        break;
                    }
                }
                else if (child is XText)
                {
                    XText text = (XText)child;
                    WriteText(text.Value, attrs);
                }
            }

            if (heading)
            {
                attrs.Pop("heading");
            }
        }
        void WriteText(string value, CssAttributes attrs)
        {
            if (value == "Created with Microsoft OneNote 2016.")
            {
                return;
            }

            // onenote output puts newlines in lots of weird places which breaks
            // markdown headings and other things.
            value = value.Replace("\n", " ");

            bool isAttribute = attrs.Find("attribute") == "true";

            if (!isAttribute)
            {
                if (attrs.GetMarginLeft() > 0.3)
                {
                    value = value.Replace("\n", " ");
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        writer.Write("    ");
                        linePos += 4;
                    }
                }
                if (attrs.Find("font-weight", false) == "bold")
                {
                    writer.Write("**");
                    value = value.Trim(whitespace);
                }
            }
            if (value.Replace("\n", " ").Contains("Did not get the expected response"))
            {
                Console.WriteLine("found it");
            }
            bool carriageReturn = false;

            for (int i = 0, length = value.Length; i < length; i++)
            {
                char ch = value[i];
                if (ch == '&')
                {
                    i++;
                    int j = value.IndexOf(';', i);
                    if (j > i)
                    {
                        string name = value.Substring(i, j - i);
                        switch (name)
                        {
                        case "amp":
                            writer.Write('&');
                            this.linePos++;
                            break;

                        case "lt":
                            writer.Write('<');
                            this.linePos++;
                            break;

                        case "gt":
                            writer.Write('>');
                            this.linePos++;
                            break;

                        case "apos":
                            writer.Write('\'');
                            this.linePos++;
                            break;

                        case "quot":
                            writer.Write('"');
                            this.linePos++;
                            break;

                        default:
                            throw new Exception("Unsupported entity: " + name);
                        }
                    }
                    else
                    {
                        writer.Write('&');
                        this.linePos++;
                    }
                }
                else if (ch == '\r')
                {
                    carriageReturn = true;
                }
                else if (ch == '\n')
                {
                    carriageReturn = false;
                    WriteLine();
                }
                else if ((ch == ' ' || ch == '\t' || ch == 0xA0) && linePos == 0)
                {
                    continue;
                }
                else
                {
                    if (carriageReturn)
                    {
                        carriageReturn = false;
                        WriteLine();
                    }
                    writer.Write(ch);
                    this.linePos++;
                }
            }
            if (!isAttribute)
            {
                if (attrs.Find("font-weight", false) == "bold")
                {
                    writer.Write("** ");
                }
            }
        }