public void build() {
    declareMethod();

    ExceptionWrapper mainTryBlock = new ExceptionWrapper(codeModel, method.body(), context);
    for (Integer arity : primitive.getArity()) {
      JInvocation invocation = invoke("doApply").arg(context).arg(environment);

      for (int i = 0; i < arity; ++i) {
        invocation.arg(args.component(lit(i)));
      }
      mainTryBlock
          .body()
          ._if(JExpr.direct("args.length").eq(JExpr.lit(arity)))
          ._then()
          ._return(invocation);
    }

    mainTryBlock.catchEvalExceptions();
    mainTryBlock.catchRuntimeExceptions();
    mainTryBlock.catchExceptions();

    method
        .body()
        ._throw(
            JExpr._new(codeModel.ref(EvalException.class))
                .arg(lit(primitive.getName() + ": max arity is " + primitive.getMaxArity())));
  }
  private void convertArguments(JBlock parent, VarArgParser parser) {
    int index = 0;
    for (VarArgParser.PositionalArg posArg : parser.getPositionalArguments()) {
      parent.assign(
          posArg.getVariable(), convert(posArg.getFormal(), args.component(lit(index++))));
    }

    JForLoop forLoop = parent._for();
    JVar loopCounter =
        forLoop.init(codeModel._ref(int.class), "i", lit(parser.getPositionalArguments().size()));
    forLoop.test(loopCounter.lt(JExpr.direct("args.length")));
    forLoop.update(loopCounter.incr());

    forLoop
        .body()
        .invoke(parser.getVarArgBuilder(), "add")
        .arg(argNames.component(loopCounter))
        .arg(args.component(loopCounter));
  }