public Annotation[] getAllMethodAnnotations(Method method, Locatable srcPos) {
   Annotation[] r = method.getAnnotations();
   for (int i = 0; i < r.length; i++) {
     r[i] = LocatableAnnotation.create(r[i], srcPos);
   }
   return r;
 }
 public Annotation[] getAllFieldAnnotations(Field field, Locatable srcPos) {
   Annotation[] r = field.getAnnotations();
   for (int i = 0; i < r.length; i++) {
     r[i] = LocatableAnnotation.create(r[i], srcPos);
   }
   return r;
 }
 public <A extends Annotation> A getMethodParameterAnnotation(
     Class<A> annotation, Method method, int paramIndex, Locatable srcPos) {
   Annotation[] pa = method.getParameterAnnotations()[paramIndex];
   for (Annotation a : pa) {
     if (a.annotationType() == annotation) return LocatableAnnotation.create((A) a, srcPos);
   }
   return null;
 }
  public <A extends Annotation> A getPackageAnnotation(Class<A> a, Class clazz, Locatable srcPos) {
    Package p = clazz.getPackage();
    if (p == null) return null;

    Map<Package, Annotation> cache = packageCache.get(a);
    if (cache == null) {
      cache = new HashMap<Package, Annotation>();
      packageCache.put(a, cache);
    }

    if (cache.containsKey(p)) return (A) cache.get(p);
    else {
      A ann = LocatableAnnotation.create(p.getAnnotation(a), srcPos);
      cache.put(p, ann);
      return ann;
    }
  }
 public <A extends Annotation> A getClassAnnotation(Class<A> a, Class clazz, Locatable srcPos) {
   return LocatableAnnotation.create(((Class<?>) clazz).getAnnotation(a), srcPos);
 }
 public <A extends Annotation> A getMethodAnnotation(
     Class<A> annotation, Method method, Locatable srcPos) {
   return LocatableAnnotation.create(method.getAnnotation(annotation), srcPos);
 }
 public <A extends Annotation> A getFieldAnnotation(
     Class<A> annotation, Field field, Locatable srcPos) {
   return LocatableAnnotation.create(field.getAnnotation(annotation), srcPos);
 }