Yesterday I showed you how we made the first two tests pass. And I also told you that Per Dervall helped to solve the rest. I asked the question on StackOverflow. And I also pinged him about this on twitter.

And the poor man made an effort to respond in VB.Net.

And in short, this is the result.

```vbnet Public Class ParseLatinPlantName

    Public Function Parse(ByVal name As String) As Plant
        Dim config = ParserFactory.Fluent()
        Dim expr = config.Rule()
        Dim subSpecies = config.Rule()
        Dim hybridIndicator = config.Expression
        hybridIndicator.ThatMatches("x").AndReturns(Function(f) f)

        Dim sp = config.Expression()
        sp.ThatMatches("sp.").AndReturns(Function(f) f)
        Dim name1 = config.Expression()
        name1.ThatMatches("w+").AndReturns(Function(f) f)
        Dim nothing1 = config.Rule()


        expr.IsMadeUp.By(name1).As("Genus") _
                .Followed.By(name1).As("Species") _
                .Followed.By(subSpecies).As("Subspecies") _
                .WhenFound(Function(f) New Plant With {.Genus = f.Genus, .Species = f.Species, .SubSpecies = f.Subspecies}) _
                .Or.By(name1).As("FirstSpecies").Followed.By(hybridIndicator).Followed.By(name1).As("SecondSpecies") _
                .WhenFound(Function(f) New Plant With {.IsHybrid = True})

        subSpecies.IsMadeUp.By(sp).Followed.By(name1).As("Subspecies").WhenFound(Function(f) f.Subspecies) _
            .Or.By(nothing1)

        Dim parser = config.CreateParser()
        Dim result = DirectCast(parser.Parse(name), Plant)
        Return result
    End Function
End Class```

And here is the C# code.

```csharp public Plant Parse(string input) { var config = ParserFactory.Fluent(); var expr = config.Rule(); var subSpecies = config.Rule(); var hybridIndicator = config.Expression(); hybridIndicator.ThatMatches(“x”).AndReturns(f => f);

        var sp = config.Expression();
        sp.ThatMatches("sp\.").AndReturns(f => f);
        var name1 = config.Expression();
        name1.ThatMatches("\w+").AndReturns(f => f);
        var nothing1 = config.Rule();


        expr.IsMadeUp.By(name1).As("Genus")
            .Followed.By(name1).As("Species")
            .Followed.By(subSpecies).As("Subspecies")
            .WhenFound(f => new Plant {Genus = f.Genus, Species = f.Species, SubSpecies = f.Subspecies})
            .Or.By(name1).As("FirstSpecies").Followed.By(hybridIndicator).Followed.By(name1).As("SecondSpecies")
            .WhenFound(f => new Plant {IsHybrid = true});

        subSpecies.IsMadeUp.By(sp).Followed.By(name1).As("Subspecies").WhenFound(f => f.Subspecies)
            .Or.By(nothing1);

        var parser = config.CreateParser();
        var result = (Plant) parser.Parse(input);
        return result;
    }
}```

I won’t repeat the explanation here, I will leave that on SO.

But I did a few performance tests. Nothing very official. Just good to know.

csharp [Test] public void SpeedTest() { var parser = new ParseLatinPlantName(); Plant result; for(int i =0; i < 10000; i++) { result = parser.Parse("Salvia x jamensis"); } } Ncrunch tells me the for loop takes 20.717 seconds.

And then I did this.

csharp var parser = new ParseLatinPlantName(); Plant result; for(int i =0; i < 10000; i++) { result = parser.Parse("Salvia x jamensis"); } for (int i = 0; i < 10000; i++) { result = parser.Parse("Salvia jamensis"); } for (int i = 0; i < 10000; i++) { result = parser.Parse("Salvia jamensis sp. something"); } The first for takes around 20 seconds the second around 25 and the third around 13 seconds.

I let you draw your own conlcusions on why that is.

I think Piglet is very cool and can be useful The fluent code is very readable. The biggest problem so far is a lack of documentation. But it can only get better.