@Override
 public void visit(Symbol name) {
   if (!unique || !set.contains(name)) {
     if (maxNames == -1 || names.length() < maxNames) {
       names.add(StringArrayVector.valueOf(name.getPrintName()));
       set.add(name);
     }
   }
 }
  private static SEXP R_loadMethod(Context context, SEXP def, String fname, Environment ev) {

    /* since this is called every time a method is dispatched with a
    definition that has a class, it should be as efficient as
    possible => we build in knowledge of the standard
    MethodDefinition and MethodWithNext slots.  If these (+ the
    class slot) don't account for all the attributes, regular
    dispatch is done. */
    int found = 1; /* we "know" the class attribute is there */

    found++; // we also have our fake __S4_BIt for renjin

    PairList attrib = def.getAttributes().asPairList();
    for (PairList.Node s : attrib.nodes()) {
      SEXP t = s.getTag();
      if (t == R_target) {
        ev.setVariable(R_dot_target, s.getValue());
        found++;
      } else if (t == R_defined) {
        ev.setVariable(R_dot_defined, s.getValue());
        found++;
      } else if (t == R_nextMethod) {
        ev.setVariable(R_dot_nextMethod, s.getValue());
        found++;
      } else if (t == Symbols.SOURCE) {
        /* ignore */ found++;
      }
    }
    ev.setVariable(R_dot_Method, def);

    /* this shouldn't be needed but check the generic being
    "loadMethod", which would produce a recursive loop */
    if (fname.equals("loadMethod")) {
      return def;
    }
    if (found < attrib.length()) {
      FunctionCall call =
          FunctionCall.newCall(R_loadMethod_name, def, StringArrayVector.valueOf(fname), ev);
      return context.evaluate(call, ev);

      //      SEXP e, val;
      //      PROTECT(e = allocVector(LANGSXP, 4));
      //      SETCAR(e, R_loadMethod_name); val = CDR(e);
      //      SETCAR(val, def); val = CDR(val);
      //      SETCAR(val, fname); val = CDR(val);
      //      SETCAR(val, ev);
      //      val = eval(e, ev);
      //      return val;
    } else {
      return def;
    }
  }
  /* C version of the standardGeneric R function. */
  public SEXP R_standardGeneric(Context context, Symbol fsym, Environment ev, SEXP fdef) {
    String fname = fsym.getPrintName();
    Environment f_env = context.getGlobalEnvironment().getBaseEnvironment();
    SEXP mlist = Null.INSTANCE;
    SEXP f;
    SEXP val = Null.INSTANCE;
    int nprotect = 0;

    //    if(!initialized)
    //      R_initMethodDispatch(NULL);

    if (fdef instanceof Closure) {
      f_env = ((Closure) fdef).getEnclosingEnvironment();
      mlist = f_env.getVariable(".Methods");
      if (mlist == Symbol.UNBOUND_VALUE) {
        mlist = Null.INSTANCE;
      }
    } else if (fdef instanceof PrimitiveFunction) {
      f_env = context.getBaseEnvironment();
      // mlist = R_primitive_methods((PrimitiveFunction)fdef);
      throw new UnsupportedOperationException();
    } else {
      throw new EvalException(
          "invalid generic function object for method selection for function '%s': expected a function or a primitive, got an object of class \"%s\"",
          fsym.getPrintName(), fdef.getAttributes().getClassVector());
    }
    if (mlist instanceof Null || mlist instanceof Closure || mlist instanceof PrimitiveFunction) {
      f = mlist;
    } else {
      // f = do_dispatch(fname, ev, mlist, TRUE, TRUE);
      throw new UnsupportedOperationException();
    }
    if (f == Null.INSTANCE) {
      SEXP value =
          R_S_MethodsListSelect(context, StringArrayVector.valueOf(fname), ev, mlist, f_env);
      if (value == Null.INSTANCE) {
        throw new EvalException(
            "no direct or inherited method for function '%s' for this call", fname);
      }
      mlist = value;
      /* now look again.  This time the necessary method should
      have been inserted in the MethodsList object */
      f = do_dispatch(context, fname, (Environment) ev, mlist, false, true);
    }
    //    /* loadMethod methods */
    if (f.isObject()) {
      f = R_loadMethod(context, f, fsym.getPrintName(), ev);
    }
    if (f instanceof Closure) {
      return R_execMethod(context, (Closure) f, ev);
    } else if (f instanceof PrimitiveFunction) {
      /* primitives  can't be methods; they arise only as the
      default method when a primitive is made generic.  In this
      case, return a special marker telling the C code to go on
      with the internal computations. */
      // val = R_deferred_default_method();
      throw new UnsupportedOperationException();
    } else {
      throw new EvalException("invalid object (non-function) used as method");
    }
    //    return val;
  }