@Override
  public OperationDefinition handle(
      FeatureCallExpression featureCallExpression, Type contextType, ArrayList<Type> argTypes)
      throws AnalysisInterruptException {

    // get the manager
    StandardLibraryOperationDefinitionContainer manager =
        OperationDefinitionManager.getInstance().getStandardLibraryOperationDefinitionContainer();

    // get the result
    OperationDefinition result =
        manager.getOperation(
            ((MethodCallExpression) featureCallExpression).getMethod().getName(), argTypes);

    if (result != null) {
      OperationDefinitionManager.getInstance().registerHandledOperationDefinition(result);

      Expression target = featureCallExpression.getTarget();

      if (target == null) {
        LogBook.getInstance()
            .addError(featureCallExpression, IMessage_TypeResolution.OPERATION_REQUIRES_TARGET);
        SetType returnType = EolFactory.eINSTANCE.createSetType();
        AnyType contentType = EolFactory.eINSTANCE.createAnyType();
        returnType.setContentType(contentType);
        result.setReturnType(returnType);
        return result;
      }

      AnyType targetType = (AnyType) EcoreUtil.copy(target.getResolvedType());

      if (targetType == null) {
        LogBook.getInstance()
            .addError(target, IMessage_TypeResolution.EXPRESSION_DOES_NOT_HAVE_A_TYPE);
        SetType returnType = EolFactory.eINSTANCE.createSetType();
        AnyType contentType = EolFactory.eINSTANCE.createAnyType();
        returnType.setContentType(contentType);
        result.setReturnType(returnType);
        return result;
      }

      SetType returnType = EolFactory.eINSTANCE.createSetType();
      AnyType contentType = EolFactory.eINSTANCE.createAnyType();
      if (TypeUtil.getInstance().isInstanceofAnyType(targetType)) {
        contentType.getDynamicTypes().addAll(targetType.getDynamicTypes());
      } else {
        contentType.getDynamicTypes().add(targetType);
      }
      returnType.setContentType(contentType);
      result.setReturnType(returnType);
      return result;
    }
    return result;
  }
  @Override
  public OperationDefinition handle(
      FeatureCallExpression featureCallExpression, Type contextType, ArrayList<Type> argTypes)
      throws AnalysisInterruptException {

    // get the manager
    StandardLibraryOperationDefinitionContainer manager =
        OperationDefinitionManager.getInstance().getStandardLibraryOperationDefinitionContainer();

    OperationDefinition result = null;

    if (contextType instanceof MapType) {
      result =
          manager.getOperation(
              ((MethodCallExpression) featureCallExpression).getMethod().getName(),
              contextType,
              argTypes);

    } else if (TypeUtil.getInstance().isInstanceofAnyType(contextType)) {
      if (TypeInferenceManager.getInstance()
          .containsDynamicType((AnyType) contextType, EolPackage.eINSTANCE.getMapType())) {
        ArrayList<Type> dyntypes =
            TypeInferenceManager.getInstance()
                .getDynamicTypes((AnyType) contextType, EolPackage.eINSTANCE.getMapType());
        result =
            manager.getOperation(
                ((MethodCallExpression) featureCallExpression).getMethod().getName(),
                dyntypes.get(0),
                argTypes);
      }
    }

    // if result is not null
    if (result != null) {

      // register the result as it has been handled
      OperationDefinitionManager.getInstance().registerHandledOperationDefinition(result);

      // get the target
      Expression target = featureCallExpression.getTarget();

      // if target is null, report and return
      if (target == null) {
        LogBook.getInstance()
            .addError(featureCallExpression, IMessage_TypeResolution.OPERATION_REQUIRES_TARGET);
        return null;
      } else {
        // get the target type copy
        Type targetType = EcoreUtil.copy(target.getResolvedType());

        // if target type is null, report and return (this will not happend)
        if (targetType == null) {
          LogBook.getInstance()
              .addError(target, IMessage_TypeResolution.EXPRESSION_DOES_NOT_HAVE_A_TYPE);
          MapType returnType = EolFactory.eINSTANCE.createMapType();
          returnType.setKeyType(EolFactory.eINSTANCE.createAnyType());
          returnType.setValueType(EolFactory.eINSTANCE.createAnyType());
          TypeResolutionContext.getInstanace().setAssets(returnType.getKeyType(), returnType);
          TypeResolutionContext.getInstanace().setAssets(returnType.getValueType(), returnType);
          result.setReturnType(returnType);
          return result;
        }
        // if target type is collection type
        if (targetType instanceof MapType) {
          MapType _targetType = (MapType) EcoreUtil.copy(targetType);
          AnyType keyType = _targetType.getKeyType();
          AnyType valueType = _targetType.getValueType();
          keyType.getDynamicTypes().clear();
          valueType.getDynamicTypes().clear();

          result.setContextType(EcoreUtil.copy(_targetType));
          result.setReturnType(_targetType);

          if (target instanceof NameExpression) {
            TypeResolutionContext.getInstanace().registerNameExpression(target, _targetType);
          }
          return result;
        }
        // else if target type is an instance of any
        else if (TypeUtil.getInstance().isInstanceofAnyType(targetType)) {

          // get dynamic types that are of type collection
          ArrayList<Type> dyntypes =
              TypeInferenceManager.getInstance()
                  .getDynamicTypes((AnyType) targetType, EolPackage.eINSTANCE.getMapType());
          if (dyntypes.size() == 0) {
            LogBook.getInstance()
                .addError(target, IMessage_TypeResolution.EXPRESSION_MAY_NOT_BE_MAP);
            MapType returnType = EolFactory.eINSTANCE.createMapType();
            returnType.setKeyType(EolFactory.eINSTANCE.createAnyType());
            returnType.setValueType(EolFactory.eINSTANCE.createAnyType());
            TypeResolutionContext.getInstanace().setAssets(returnType.getKeyType(), returnType);
            TypeResolutionContext.getInstanace().setAssets(returnType.getValueType(), returnType);
            result.setReturnType(returnType);
            return result;
          } else {

            for (Type t : dyntypes) {
              MapType _targetType = (MapType) EcoreUtil.copy(t);
              AnyType keyType = _targetType.getKeyType();
              AnyType valueType = _targetType.getValueType();
              keyType.getDynamicTypes().clear();
              valueType.getDynamicTypes().clear();
            }
            result.setReturnType(EcoreUtil.copy(targetType));
            if (target instanceof NameExpression) {
              TypeResolutionContext.getInstanace()
                  .registerNameExpression(target, EcoreUtil.copy(targetType));
            }
            return result;
          }
        } else {
          LogBook.getInstance().addError(target, IMessage_TypeResolution.EXPRESSION_MAY_NOT_BE_MAP);
          MapType returnType = EolFactory.eINSTANCE.createMapType();
          returnType.setKeyType(EolFactory.eINSTANCE.createAnyType());
          returnType.setValueType(EolFactory.eINSTANCE.createAnyType());
          TypeResolutionContext.getInstanace().setAssets(returnType.getKeyType(), returnType);
          TypeResolutionContext.getInstanace().setAssets(returnType.getValueType(), returnType);
          result.setReturnType(returnType);
          return result;
        }
      }
    }
    return result;
  }