public override EvaluationResult evaluate(Position position, CalculationFunctions functions, string firstToken, IList <string> remainingTokens)
        {
            MetaBean metaBean = MetaBean.of(position.GetType());

            // position
            Optional <string> positionPropertyName = metaBean.metaPropertyMap().Keys.Where(p => p.equalsIgnoreCase(firstToken)).First();

            if (positionPropertyName.Present)
            {
                object propertyValue = metaBean.metaProperty(positionPropertyName.get()).get((Bean)position);
                return(propertyValue != null?EvaluationResult.success(propertyValue, remainingTokens) : EvaluationResult.failure("Property '{}' not set", firstToken));
            }

            // position info
            Optional <string> positionInfoPropertyName = position.Info.propertyNames().Where(p => p.equalsIgnoreCase(firstToken)).First();

            if (positionInfoPropertyName.Present)
            {
                object propertyValue = position.Info.property(positionInfoPropertyName.get()).get();
                return(propertyValue != null?EvaluationResult.success(propertyValue, remainingTokens) : EvaluationResult.failure("Property '{}' not set", firstToken));
            }

            // not found
            return(invalidTokenFailure(position, firstToken));
        }