@Override
 public Object invoke(Object proxy, Method method, Object[] args) {
   String member = method.getName();
   Class[] paramTypes = method.getParameterTypes();
   // Handle Object and Annotation methods
   if (member.equals("equals") && paramTypes.length == 1 && paramTypes[0] == Object.class)
     return metadata.isEqual(args[0]);
   if (member.equals("toString")) return metadata.toString();
   if (member.equals("hashCode")) return metadata.hashCode();
   if (member.equals("annotationType")) return metadata.getType();
   // Handle annotation member accessors
   return metadata.get(member);
 }
 @SuppressWarnings({"unchecked"})
 public static <T extends Annotation> T buildRandomAnnotation(Class<T> annotationClass) {
   return (T)
       Proxy.newProxyInstance(
           annotationClass.getClassLoader(),
           new Class<?>[] {annotationClass},
           new AnnotationHandler(AnnotationMetadata.randomAnnotation(annotationClass)));
 }