@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      if (method.getDeclaringClass() == Object.class) {
        if ("getClass".equals(method.getName()))
          return array.type.type();
        else
          return method.invoke(this, args);
      }
      MethodModel hm = array.type.method(method);
      switch (hm.methodType()) {
        case SETTER:
          array.set(n, hm.fieldModel(), args[0]);
          return proxy;
        case GETTER:
          return array.get(n, hm.fieldModel());
        default:
          throw new UnsupportedOperationException();
      }
    }