public static Parameter deriveTypedParameter(
      String name,
      String expression,
      Object evaluatedResult,
      TagList tags,
      ParamMode paramMode,
      Map<String, Object> paramMeta) {
    if (evaluatedResult instanceof String) {
      return StringParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof Long) {
      return LongParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof Double) {
      return DoubleParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof Boolean) {
      return BooleanParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof Map) {
      return MapParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof List) {
      List<?> list = (List<?>) evaluatedResult;
      if (!list.isEmpty()) {
        Object item = list.get(0);
        if (item instanceof String) {
          return StringArrayParameter.builder()
              .name(name)
              .expression(expression)
              .tags(tags)
              .mode(paramMode)
              .meta(paramMeta)
              .build();
        } else if (item instanceof Long) {
          return LongArrayParameter.builder()
              .name(name)
              .expression(expression)
              .tags(tags)
              .mode(paramMode)
              .meta(paramMeta)
              .build();
        } else if (item instanceof Double || item instanceof BigDecimal) {
          return DoubleArrayParameter.builder()
              .name(name)
              .expression(expression)
              .tags(tags)
              .mode(paramMode)
              .meta(paramMeta)
              .build();
        } else if (item instanceof Boolean) {
          return BooleanArrayParameter.builder()
              .name(name)
              .expression(expression)
              .tags(tags)
              .mode(paramMode)
              .meta(paramMeta)
              .build();
        }
      }
    } else if (evaluatedResult instanceof String[]) {
      return StringArrayParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof long[]) {
      return LongArrayParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof double[]) {
      return DoubleArrayParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    } else if (evaluatedResult instanceof boolean[]) {
      return BooleanArrayParameter.builder()
          .name(name)
          .expression(expression)
          .tags(tags)
          .mode(paramMode)
          .meta(paramMeta)
          .build();
    }
    throw new MaestroInternalError(
        "Param [%s] type [%s] is not supported.", name, evaluatedResult.getClass().getName());
  }
@Test
  public void testDeriveTypedParameter() {
    Parameter param = ParamHelper.deriveTypedParameter("foo", "test-expr", 123L, null, null, null);
    assertEquals(ParamType.LONG, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", Boolean.TRUE, null, null, null);
    assertEquals(ParamType.BOOLEAN, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", 12.3, null, null, null);
    assertEquals(ParamType.DOUBLE, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", "bar", null, null, null);
    assertEquals(ParamType.STRING, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo", "test-expr", Collections.emptyMap(), null, null, null);
    assertEquals(ParamType.MAP, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", new long[0], null, null, null);
    assertEquals(ParamType.LONG_ARRAY, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", new boolean[0], null, null, null);
    assertEquals(ParamType.BOOLEAN_ARRAY, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", new double[0], null, null, null);
    assertEquals(ParamType.DOUBLE_ARRAY, param.getType());
    param = ParamHelper.deriveTypedParameter("foo", "test-expr", new String[0], null, null, null);
    assertEquals(ParamType.STRING_ARRAY, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo", "test-expr", Collections.singletonList(123L), null, null, null);
    assertEquals(ParamType.LONG_ARRAY, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo", "test-expr", Collections.singletonList(true), null, null, null);
    assertEquals(ParamType.BOOLEAN_ARRAY, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo", "test-expr", Collections.singletonList(12.3), null, null, null);
    assertEquals(ParamType.DOUBLE_ARRAY, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo",
            "test-expr",
            Collections.singletonList(new BigDecimal("12.3")),
            null,
            null,
            null);
    assertEquals(ParamType.DOUBLE_ARRAY, param.getType());
    param =
        ParamHelper.deriveTypedParameter(
            "foo", "test-expr", Collections.singletonList("bar"), null, null, null);
    assertEquals(ParamType.STRING_ARRAY, param.getType());
  }