public static IEnumerable <Entry> Parse(TextReader reader)
        {
            string     line;
            var        radical = default(Radical);
            var        result  = new List <Entry>();
            List <int> kanji   = null;

            while ((line = reader.ReadLine()) != null)
            {
                if (line.StartsWith("#", StringComparison.Ordinal))
                {
                    continue;
                }
                if (line.StartsWith("$", StringComparison.Ordinal))
                {
                    if (kanji != null)
                    {
                        result.Add(new Entry(radical, kanji));
                    }

                    kanji = new List <int>();
                    line  = line.Remove(0, 2);
                    var components  = line.Split(' ');
                    int codePoint   = char.ConvertToUtf32(components[0].Trim(), 0);
                    int strokeCount = int.Parse(components[1]);
                    radical = new Radical(codePoint, strokeCount);
                }
                else
                {
                    if (kanji == null)
                    {
                        throw new InvalidDataException();
                    }

                    foreach (var codePoint in AsCodePoints(line.Trim()))
                    {
                        kanji.Add(codePoint);
                    }
                }
            }

            if (kanji?.Count != 0)
            {
                result.Add(new Entry(radical, kanji));
            }

            return(result
                   .GroupBy(e => e.Radical.CodePoint)
                   .Select(g =>
            {
                var codePoint = g.Key;
                var strokeCount = g.First().Radical.StrokeCount;
                var k = g.SelectMany(e => e.KanjiCodePoints).ToList();
                return new Entry(new Radical(codePoint, strokeCount), k);
            }));
        }
 public Entry(Radical radical, IReadOnlyCollection <int> kanjiCodePoints)
 {
     Radical         = radical;
     KanjiCodePoints = kanjiCodePoints;
 }