public PracticeReplacer(Th10Converter parent)
            {
                this.evaluator = new MatchEvaluator(match =>
                {
                    var level = LevelParser.Parse(match.Groups[1].Value);
                    var chara = (CharaWithTotal)CharaParser.Parse(match.Groups[2].Value);
                    var stage = StageParser.Parse(match.Groups[3].Value);

                    if (level == Level.Extra)
                    {
                        return(match.ToString());
                    }
                    if (stage == Stage.Extra)
                    {
                        return(match.ToString());
                    }

                    if (parent.allScoreData.ClearData.ContainsKey(chara))
                    {
                        var key       = new LevelStagePair(level, stage);
                        var practices = parent.allScoreData.ClearData[chara].Practices;
                        return(practices.ContainsKey(key)
                            ? Utils.ToNumberString(practices[key].Score * 10) : "0");
                    }
                    else
                    {
                        return("0");
                    }
                });
            }
            public ClearData(Chapter chapter)
                : base(chapter)
            {
                if (!this.Signature.Equals(ValidSignature, StringComparison.Ordinal))
                {
                    throw new InvalidDataException("Signature");
                }
                if (this.Version != ValidVersion)
                {
                    throw new InvalidDataException("Version");
                }
                if (this.Size != ValidSize)
                {
                    throw new InvalidDataException("Size");
                }

                var levels            = Utils.GetEnumerator <Level>();
                var levelsExceptExtra = levels.Where(lv => lv != Level.Extra);
                var stages            = Utils.GetEnumerator <Stage>();
                var stagesExceptExtra = stages.Where(st => st != Stage.Extra);
                var numLevels         = levels.Count();
                var numPairs          = levelsExceptExtra.Count() * stagesExceptExtra.Count();

                this.Rankings    = new Dictionary <Level, ScoreData[]>(numLevels);
                this.ClearCounts = new Dictionary <Level, int>(numLevels);
                this.Practices   = new Dictionary <LevelStagePair, Practice>(numPairs);
                this.Cards       = new Dictionary <int, SpellCard>(CardTable.Count);

                using (var stream = new MemoryStream(this.Data, false))
                {
                    var reader = new BinaryReader(stream);

                    this.Chara = (CharaWithTotal)reader.ReadInt32();

                    foreach (var level in levels)
                    {
                        if (!this.Rankings.ContainsKey(level))
                        {
                            this.Rankings.Add(level, new ScoreData[10]);
                        }
                        for (var rank = 0; rank < 10; rank++)
                        {
                            var score = new ScoreData();
                            score.ReadFrom(reader);
                            this.Rankings[level][rank] = score;
                        }
                    }

                    this.TotalPlayCount = reader.ReadInt32();
                    this.PlayTime       = reader.ReadInt32();

                    foreach (var level in levels)
                    {
                        var clearCount = reader.ReadInt32();
                        if (!this.ClearCounts.ContainsKey(level))
                        {
                            this.ClearCounts.Add(level, clearCount);
                        }
                    }

                    foreach (var level in levelsExceptExtra)
                    {
                        foreach (var stage in stagesExceptExtra)
                        {
                            var practice = new Practice();
                            practice.ReadFrom(reader);
                            var key = new LevelStagePair(level, stage);
                            if (!this.Practices.ContainsKey(key))
                            {
                                this.Practices.Add(key, practice);
                            }
                        }
                    }

                    for (var number = 0; number < CardTable.Count; number++)
                    {
                        var card = new SpellCard();
                        card.ReadFrom(reader);
                        if (!this.Cards.ContainsKey(card.Id))
                        {
                            this.Cards.Add(card.Id, card);
                        }
                    }
                }
            }