class SpelKeyGenerator extends CachedExpressionEvaluator implements KeyGenerator {

  @Override
  public List<String> resolveKeys(final String lockKeyPrefix, final String expression, final Object object, final Method method, final Object[] args) {
    final Object expressionValue = evaluateExpression(expression, object, method, args);
    final List<String> keys = convertResultToList(expressionValue);

    if (keys.stream().anyMatch(Objects::isNull)) {
      throw new EvaluationConvertException("null keys are not supported: " + keys);
    }

    if (StringUtils.isEmpty(lockKeyPrefix)) {
      return keys;
    }

    return keys.stream().map(key -> lockKeyPrefix + key).collect(Collectors.toList());
  }

}

class SpelKeyGeneratorTest {

  private final KeyGenerator keyGenerator;
  private final MessageService service;
  private final Method sendMessageMethod;

  @Test
  public void shouldGenerateMultipleKeysFromContextAndVariablesWithList() {

    final String expression = "T(com.github.alturkovic.lock.key.SpelKeyGeneratorTest).generateKeys(#message)";
    assertThat(keyGenerator.resolveKeys("lock_", expression, service, sendMessageMethod, new Object[]{"p_"}))
      .containsExactly("lock_p_first", "lock_p_second");
  }

}