@Override
  public SelType call(String methodName, SelType[] args) {
    if (args.length == 0 && "size".equals(methodName)) {
      return SelLong.of(val == null ? 0 : val.size());
    } else if (args.length == 1 && "get".equals(methodName)) {
      if (!val.containsKey((SelString) args[0])) {
        return NULL;
      }
      return val.get((SelString) args[0]);
    } else if (args.length == 1 && "containsKey".equals(methodName)) {
      return SelBoolean.of(val != null && val.containsKey((SelString) args[0]));
    } else if (args.length == 2 && "put".equals(methodName)) {
      SelType value = args[1] == null ? NULL : args[1];
      SelType res = val.put((SelString) args[0], value);
      if (res == null) {
        return NULL;
      }
      return res;
    } else if (args.length == 2 && "getOrDefault".equals(methodName)) {
      if (!val.containsKey((SelString) args[0])) {
        return args[1];
      }
      return val.get((SelString) args[0]);
    }
    throw new UnsupportedOperationException(
        type()
            + " DO NOT support calling method: "
            + methodName
            + " with args: "
            + Arrays.toString(args));
  }
@Test(expected = ClassCastException.class)
  public void testCallGetNullKey() {
    orig.call("get", new SelType[] {SelType.NULL});
  }