private int _evaluateForRight(EvaluationData <GP> evaluationData)
        {
            (Maybe <EvaluationRecord> toad, Maybe <EvaluationRecord> frog)cached =
                _cache.Lookup(evaluationData.Position);
            if (cached.frog.HasValue && cached.frog.Value.IsComplete)
            {
                return(cached.frog.Value.Value);
            }


            OptionRecord optionRecord =
                new OptionRecord(
                    evaluationData.Position.GetRightOptions(),
                    int.MaxValue,
                    cached.frog
                    );

            if (optionRecord.NoPossibleMoves)
            {
                return(EvaluateEndPositionForLeft(evaluationData.Position));
            }

            EvaluationRecord record = _updateEvaluation(
                evaluationData,
                optionRecord,
                _evaluateForLeft,
                (x, y) => Math.Min(x, y),
                x => (evaluationData.BestLeft, Math.Min(x, evaluationData.BestRight)));

            _cache.Store(evaluationData.Position, (cached.toad, record.ToMaybe()));
            return(record.Value);
        }
        private EvaluationRecord _updateEvaluation(
            EvaluationData <GP> evaluationData,
            OptionRecord optionRecord,
            _evaluator nextEvaluator,
            _bestValueUpdater bestValueUpdater,
            _bestPairUpdater bestPairUpdater)
        {
            EvaluationData <GP> resultingEvaluationData;

            int bestToad = evaluationData.BestLeft;
            int bestFrog = evaluationData.BestRight;
            int optionEvaluationcount            = 0;
            int bestValue                        = optionRecord.BestValueSoFar;
            List <GamePosition> evaluatedOptions =
                optionRecord.EvaluatedOptions;

            foreach (GP option in optionRecord.OptionsToEvaluate)
            {
                optionEvaluationcount++;
                evaluatedOptions.Add(option);
                resultingEvaluationData = new EvaluationData <GP>(
                    option,
                    evaluationData.Depth + 1,
                    evaluationData.BestLeft,
                    evaluationData.BestRight);

                bestValue =
                    bestValueUpdater(
                        bestValue,
                        nextEvaluator(resultingEvaluationData));

                (bestToad, bestFrog) = bestPairUpdater(bestValue);
                if (bestToad > bestFrog)
                {
                    break;
                }
            }

            return
                (optionEvaluationcount == optionRecord.OptionsToEvaluate.Count
                ? new EvaluationRecord(bestValue)
                : new EvaluationRecord(bestValue, evaluatedOptions));
        }