@Override
  public void eval(final ExecutionContext context) {
    /*
     * Eval left
     */
    context.newCallStackFrame(LEFT_POS);
    left.eval(context);
    context.returnFromCallFrame();
    /*
     * If it is a function pointer, then create a new function call
     */
    final Object target = left.getAnnotation();
    if (isApply && target instanceof FunctionDefinition) {
      final FunctionDefinition fd = (FunctionDefinition) target;
      /*
       * Currently, there is no change in the codepath when superscript is
       * executed: f.apply(...) is exactly equivalent to f(...).
       */
      final FunctionCall fc;
      final boolean hasCall = getSuperscript() instanceof FunctionCall;
      final FunctionCall prevFC = hasCall ? (FunctionCall) getSuperscript() : null;
      if (hasCall && fd.equals(prevFC.getFunctionDefinition())) {
        fc = prevFC;
      } else {
        fc = new FunctionCall(fd, deepCopyBranches());
      }
      setSuperscript(fc);
      fc.eval(context);
      setAnnotation(fc.getAnnotation());
    } else {
      /*
       * Otherwise, evaluate branches and proceed to evaluation
       */
      projectAndEval(context);
      /*
       *  Check everything for fields
       */
      final Stream<?> argsstr = getBranchesAnnotationStream();
      final Object[] args = argsstr.toArray();
      /*
       *  collect any field indices
       */

      List<Integer> list = new ArrayList<>();
      for (Object o : args) {
        if (Field.class.isAssignableFrom(o.getClass())) {
          list.add(ArrayUtils.indexOf(args, o));
        }
      }
      final int[] fieldIndexes = new int[list.size()];
      for (Integer i : list) {
        fieldIndexes[i] = list.get(i);
      }
      // End

      /*
       *  if there are any fields, do a field apply:
       */
      final boolean fieldTarget = target instanceof Field;
      if (fieldTarget || fieldIndexes.length > 0) {
        /*
         * Run on every element of the field, and at each iteration use the
         * current annotation as corresponding element for the field. Once
         * done, set the entire field as annotation.
         */
        final Field res =
            Fields.apply(
                new BiFunction<Object, Object[], Object>() {
                  @Override
                  public Object apply(Object actualT, Object[] actualA) {
                    return ReflectionUtils.invokeBestNotStatic(actualT, methodName, actualA);
                  }
                },
                fieldTarget,
                fieldIndexes,
                target,
                args);
        setAnnotation(res);
      } else {
        final Object annotation = ReflectionUtils.invokeBestNotStatic(target, methodName, args);
        setAnnotation(annotation);
      }
    }
  }