@Override
  @Nullable
  protected Object evaluateCall(@NotNull PyCallExpression expression) {
    final PyExpression[] args = expression.getArguments();
    if (expression.isCalleeText("resolve")) {
      PyReferenceExpression callee = (PyReferenceExpression)expression.getCallee();
      if (callee != null && callee.getQualifier() instanceof PyCallExpression) {
        return evaluate(callee.getQualifier());
      }
    }
    if (expression.isCalleeText("Path") && args.length >= 1) {
      return evaluate(args[0]);
    }
    if (expression.isCalleeText(PyNames.DIRNAME) && args.length == 1) {
      Object argValue = evaluate(args[0]);
      return argValue instanceof String ? Paths.get((String) argValue).getParent().toFile().getPath() : null;
    }
    else if (expression.isCalleeText(PyNames.JOIN) && args.length >= 1) {
      return evaluatePathInJoin(args, args.length);
    }
    else if (expression.isCalleeText(PyNames.NORMPATH, PyNames.REALPATH) && args.length == 1) {
      // we don't care about the exact transformation performed by python but need to preserve the availability of the path
      return evaluate(args[0]);
    }
    else if (expression.isCalleeText(PyNames.ABSPATH) && args.length == 1) {
      Object argValue = evaluate(args[0]);
      // relative to directory of 'containingFilePath', not file
      if (!(argValue instanceof String)) {
        return null;
      }
      if (FileUtil.isAbsolutePlatformIndependent((String)argValue)) {
        return argValue;
      }
      else {
        String path = Paths.get(myContainingFilePath).resolveSibling((String)argValue).toFile().getPath();
        return FileUtil.toSystemIndependentName(path);
      }
    }
    return super.evaluateCall(expression);
  }
@Override
  @Nullable
  protected Object evaluateCall(@NotNull PyCallExpression expression)