public async Task GetOuterHtmlForFirst()
            {
                // Given
                const string input    = @"<html>
                        <head>
                            <title>Foobar</title>
                        </head>
                        <body>
                            <h1>Title</h1>
                            <p>This is some Foobar text</p>
                            <p>This is some other text</p>
                        </body>
                    </html>";
                TestDocument document = new TestDocument(input);
                QueryHtml    query    = new QueryHtml("p")
                                        .GetOuterHtml("Key")
                                        .First();

                // When
                IReadOnlyList <TestDocument> results = await ExecuteAsync(document, query);

                // Then
                results.Select(x => x["Key"].ToString()).ShouldBe(new[]
                {
                    "<p>This is some Foobar text</p>"
                });
            }
            public async Task GetTextContent()
            {
                // Given
                const string input    = @"<html>
                        <head>
                            <title>Foobar</title>
                        </head>
                        <body>
                            <h1>Title</h1>
                            <p>This is some <b>Foobar</b> text</p>
                            <p>This is some other text</p>
                        </body>
                    </html>";
                TestDocument document = new TestDocument(input);
                QueryHtml    query    = new QueryHtml("p")
                                        .GetTextContent("TextContentKey");

                // When
                IReadOnlyList <IDocument> results = await ExecuteAsync(document, query);

                // Then
                results.Select(x => x.GetString("TextContentKey")).ShouldBe(new[]
                {
                    "This is some Foobar text",
                    "This is some other text"
                });
            }
            public async Task GetAttributeValueWithMoreThanOneMatch()
            {
                // Given
                const string input    = @"<html>
                        <head>
                            <title>Foobar</title>
                        </head>
                        <body>
                            <h1>Title</h1>
                            <p foo=""bar"" foo=""bat"">This is some <b>Foobar</b> text</p>
                            <p foo=""baz"">This is some other text</p>
                        </body>
                    </html>";
                TestDocument document = new TestDocument(input);
                QueryHtml    query    = new QueryHtml("p")
                                        .GetAttributeValue("foo");

                // When
                IReadOnlyList <IDocument> results = await ExecuteAsync(document, query);

                // Then
                results.Select(x => x.GetString("foo")).ShouldBe(new[]
                {
                    "bar",
                    "baz"
                });
            }
            public async Task GetAll()
            {
                // Given
                const string input    = @"<html>
                        <head>
                            <title>Foobar</title>
                        </head>
                        <body>
                            <h1>Title</h1>
                            <p foo=""bar"" foo=""bat"" a=""A"" b=""B"">This is some <b>Foobar</b> text</p>
                            <p foo=""baz"" x=""X"">This is some other text</p>
                        </body>
                    </html>";
                TestDocument document = new TestDocument(input);
                QueryHtml    query    = new QueryHtml("p")
                                        .GetAll();

                // When
                List <IOrderedEnumerable <KeyValuePair <string, object> > > results = (await ExecuteAsync(document, query))
                                                                                      .Select(x => x.OrderBy(y => y.Key, StringComparer.OrdinalIgnoreCase))
                                                                                      .ToList();

                // Then
                results.Count.ShouldBe(2);
                new[]
                {
                    new KeyValuePair <string, object>("a", "A"),
                    new KeyValuePair <string, object>("b", "B"),
                    new KeyValuePair <string, object>("foo", "bar"),
                    new KeyValuePair <string, object>("InnerHtml", "This is some <b>Foobar</b> text"),
                    new KeyValuePair <string, object>("OuterHtml", @"<p foo=""bar"" a=""A"" b=""B"">This is some <b>Foobar</b> text</p>"),
                    new KeyValuePair <string, object>("TextContent", "This is some Foobar text")
                }.ShouldBeSubsetOf(results[0]);
                new[]
                {
                    new KeyValuePair <string, object>("foo", "baz"),
                    new KeyValuePair <string, object>("InnerHtml", "This is some other text"),
                    new KeyValuePair <string, object>("OuterHtml", @"<p foo=""baz"" x=""X"">This is some other text</p>"),
                    new KeyValuePair <string, object>("TextContent", "This is some other text"),
                    new KeyValuePair <string, object>("x", "X")
                }.ShouldBeSubsetOf(results[1]);
            }
            public async Task SetOuterHtmlContentWithMetadata()
            {
                // Given
                const string input    = @"<html>
                        <head>
                            <title>Foobar</title>
                        </head>
                        <body>
                            <h1>Title</h1>
                            <p>This is some Foobar text</p>
                            <p>This is some other text</p>
                        </body>
                    </html>";
                TestDocument document = new TestDocument(input);
                QueryHtml    query    = new QueryHtml("p")
                                        .SetContent()
                                        .GetInnerHtml("InnerHtmlKey")
                                        .GetOuterHtml("OuterHtmlKey");

                // When
                IReadOnlyList <IDocument> results = await ExecuteAsync(document, query);

                // Then
                results.Select(x => ((TestDocument)x).Content).ShouldBe(new[]
                {
                    "<p>This is some Foobar text</p>",
                    "<p>This is some other text</p>"
                });
                results.Select(x => x.GetString("InnerHtmlKey")).ShouldBe(new[]
                {
                    "This is some Foobar text",
                    "This is some other text"
                });
                results.Select(x => x.GetString("OuterHtmlKey")).ShouldBe(new[]
                {
                    "<p>This is some Foobar text</p>",
                    "<p>This is some other text</p>"
                });
            }