@Override
 public IOpenClass addType(String namespace, IOpenClass type) throws OpenLCompilationException {
   if (type instanceof CustomDynamicOpenClass) {
     CustomDynamicOpenClass customDynamicOpenClass = (CustomDynamicOpenClass) type;
     IOpenClass openClass = findType(namespace, type.getName());
     if (openClass == null) {
       return super.addType(namespace, customDynamicOpenClass.copy());
     } else {
       customDynamicOpenClass.updateOpenClass(openClass);
       return openClass;
     }
   } else {
     return super.addType(namespace, type);
   }
 }
  @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());
  }