private Object[] getPossibleValues(
      MethodParameter methodParameter, AnnotatedParameters actionDescriptor) {
    try {
      Class<?> parameterType = methodParameter.getNestedParameterType();
      Object[] possibleValues;
      Class<?> nested;
      if (Enum[].class.isAssignableFrom(parameterType)) {
        possibleValues = parameterType.getComponentType().getEnumConstants();
      } else if (Enum.class.isAssignableFrom(parameterType)) {
        possibleValues = parameterType.getEnumConstants();
      } else if (Collection.class.isAssignableFrom(parameterType)
          && Enum.class.isAssignableFrom(
              nested = TypeDescriptor.nested(methodParameter, 1).getType())) {
        possibleValues = nested.getEnumConstants();
      } else {
        Select select = methodParameter.getParameterAnnotation(Select.class);
        if (select != null) {
          Class<? extends Options> optionsClass = select.options();
          Options options = optionsClass.newInstance();
          // collect call values to pass to options.get
          List<Object> from = new ArrayList<Object>();
          for (String paramName : select.args()) {
            AnnotatedParameter parameterValue = actionDescriptor.getAnnotatedParameter(paramName);
            if (parameterValue != null) {
              from.add(parameterValue.getCallValue());
            }
          }

          Object[] args = from.toArray();
          possibleValues = options.get(select.value(), args);
        } else {
          possibleValues = new Object[0];
        }
      }
      return possibleValues;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }