@Test
  public void simpleLookup4paramNotEnoughValues() {
    IOpenMethod method =
        getJavaWrapper()
            .getOpenClass()
            .getMethod(
                "SimpleLookup4paramNotEnoughValues",
                new IOpenClass[] {
                  JavaOpenClass.STRING,
                  JavaOpenClass.getOpenClass(Double.class),
                  JavaOpenClass.INT,
                  JavaOpenClass.INT
                });
    Object wrapperInstance = getJavaWrapper().newInstance();

    assertEquals(
        new DoubleValue(0.9),
        method.invoke(wrapperInstance, new Object[] {"DE", 0d, 7, 3}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(1),
        method.invoke(wrapperInstance, new Object[] {"DE", 0d, 10, 4}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(56),
        method.invoke(wrapperInstance, new Object[] {"", 1d, 9, 3}, getJavaWrapper().getEnv()));
  }
  @Test
  public void simpleLookupRange1() {
    IOpenMethod method =
        getJavaWrapper()
            .getOpenClass()
            .getMethod(
                "SimpleLookupRange1",
                new IOpenClass[] {JavaOpenClass.STRING, JavaOpenClass.getOpenClass(Double.class)});
    Object wrapperInstance = getJavaWrapper().newInstance();

    assertEquals(
        new DoubleValue(0.9),
        method.invoke(wrapperInstance, new Object[] {"DE", 25}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(1),
        method.invoke(wrapperInstance, new Object[] {"", 4}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(0),
        method.invoke(wrapperInstance, new Object[] {"DE", 3}, getJavaWrapper().getEnv()));
  }
  @Test
  public void simpleLookup3paramRangeArray() {
    IOpenMethod method =
        getJavaWrapper()
            .getOpenClass()
            .getMethod(
                "SimpleLookup3paramRangeArray",
                new IOpenClass[] {
                  JavaOpenClass.STRING, JavaOpenClass.getOpenClass(Double.class), JavaOpenClass.INT
                });
    Object wrapperInstance = getJavaWrapper().newInstance();

    assertEquals(
        new DoubleValue(0),
        method.invoke(wrapperInstance, new Object[] {"DE", 5d, 5}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(0.9),
        method.invoke(wrapperInstance, new Object[] {"DE", 7d, 3}, getJavaWrapper().getEnv()));
    assertEquals(
        new DoubleValue(1),
        method.invoke(wrapperInstance, new Object[] {"DE", 10d, 4}, getJavaWrapper().getEnv()));
  }
  @SuppressWarnings("unchecked")
  public static IConditionEvaluator makeEvaluator(
      ICondition condition, IOpenClass methodType, IBindingContext bindingContext)
      throws SyntaxNodeException {

    IParameterDeclaration[] params = condition.getParams();

    switch (params.length) {
      case 1:
        IOpenClass paramType = params[0].getType();

        IOpenCast openCast = bindingContext.getCast(paramType, methodType);

        if (openCast != null) {
          return new EqualsIndexedEvaluator(openCast);
        }

        IAggregateInfo aggregateInfo = paramType.getAggregateInfo();

        if (aggregateInfo.isAggregate(paramType)
            && aggregateInfo.getComponentType(paramType).isAssignableFrom(methodType)) {
          return new ContainsInArrayIndexedEvaluator();
        }

        IRangeAdaptor<? extends Object, ? extends Comparable<?>> rangeAdaptor =
            getRangeAdaptor(methodType, paramType);

        if (rangeAdaptor != null) {
          return new RangeIndexedEvaluator(
              (IRangeAdaptor<Object, ? extends Comparable<Object>>) rangeAdaptor, 1);
        }

        if (JavaOpenClass.BOOLEAN.equals(methodType)
            || JavaOpenClass.getOpenClass(Boolean.class).equals(methodType)) {
          return new DefaultConditionEvaluator();
        }

        break;

      case 2:
        IOpenClass paramType0 = params[0].getType();
        IOpenClass paramType1 = params[1].getType();

        if (methodType == paramType0 && methodType == paramType1) {

          Class<?> clazz = methodType.getInstanceClass();

          if (clazz != short.class
              && clazz != byte.class
              && clazz != int.class
              && clazz != long.class
              && clazz != double.class
              && clazz != float.class
              && !Comparable.class.isAssignableFrom(clazz)) {
            String message = String.format("Type '%s' is not Comparable", methodType.getName());
            throw SyntaxNodeExceptionUtils.createError(
                message, null, null, condition.getSourceCodeModule());
          }

          return new RangeIndexedEvaluator(null, 2);
        }

        aggregateInfo = paramType1.getAggregateInfo();

        if (aggregateInfo.isAggregate(paramType1)
            && aggregateInfo.getComponentType(paramType1) == methodType) {

          BooleanTypeAdaptor booleanTypeAdaptor = BooleanAdaptorFactory.getAdaptor(paramType0);

          if (booleanTypeAdaptor != null) {
            return new ContainsInOrNotInArrayIndexedEvaluator(booleanTypeAdaptor);
          }
        }

        if (JavaOpenClass.BOOLEAN.equals(methodType)
            || JavaOpenClass.getOpenClass(Boolean.class).equals(methodType)) {
          return new DefaultConditionEvaluator();
        }

        break;
    }

    List<String> names = new ArrayList<String>();

    for (IParameterDeclaration parameterDeclaration : params) {

      String name = parameterDeclaration.getType().getName();
      names.add(name);
    }

    String parametersString = StringUtils.join(names, ",");

    String message =
        String.format(
            "Can not make a Condition Evaluator for parameter %s and [%s]",
            methodType.getName(), parametersString);

    throw SyntaxNodeExceptionUtils.createError(
        message, null, null, condition.getSourceCodeModule());
  }