private Object addArrayValue(
      Object proxy, String name, Class itemType, Class expectedReturnType, Object arg) {
    if (arrays == null) arrays = new HashMap<String, JAnnotationArrayMember>();
    JAnnotationArrayMember m = arrays.get(name);
    if (m == null) {
      m = use.paramArray(name);
      arrays.put(name, m);
    }

    // sub annotation
    if (Annotation.class.isAssignableFrom(itemType)) {
      Class<? extends Annotation> r = (Class<? extends Annotation>) itemType;
      if (!JAnnotationWriter.class.isAssignableFrom(expectedReturnType))
        throw new IllegalArgumentException("Unexpected return type " + expectedReturnType);
      return new TypedAnnotationWriter(r, expectedReturnType, m.annotate(r)).createProxy();
    }

    // primitive
    if (arg instanceof JType) {
      checkType(Class.class, itemType);
      m.param((JType) arg);
      return proxy;
    }
    checkType(arg.getClass(), itemType);
    if (arg instanceof String) {
      m.param((String) arg);
      return proxy;
    }
    if (arg instanceof Boolean) {
      m.param((Boolean) arg);
      return proxy;
    }
    if (arg instanceof Integer) {
      m.param((Integer) arg);
      return proxy;
    }
    if (arg instanceof Class) {
      m.param((Class) arg);
      return proxy;
    }
    // TODO: enum constant. how should we handle it?

    throw new IllegalArgumentException("Unable to handle this method call ");
  }