class PositionTokenEvaluator extends TokenEvaluator<Position> {

  @Override
  public EvaluationResult evaluate(
      Position position,
      CalculationFunctions functions,
      String firstToken,
      List<String> remainingTokens) {

    MetaBean metaBean = MetaBean.of(position.getClass());

    // position
    Optional<String> positionPropertyName = metaBean.metaPropertyMap().keySet().stream()
        .filter(p -> p.equalsIgnoreCase(firstToken))
        .findFirst();
    if (positionPropertyName.isPresent()) {
      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.getInfo().propertyNames().stream()
        .filter(p -> p.equalsIgnoreCase(firstToken))
        .findFirst();
    if (positionInfoPropertyName.isPresent()) {
      Object propertyValue = position.getInfo().property(positionInfoPropertyName.get()).get();
      return propertyValue != null ?
          EvaluationResult.success(propertyValue, remainingTokens) :
          EvaluationResult.failure("Property '{}' not set", firstToken);
    }

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

}