@Override
 public Void visit(ConstructorDeclaration decl, AElement elem) {
   int i = 0;
   List<Parameter> params = decl.getParameters();
   List<AnnotationExpr> rcvrAnnos = decl.getReceiverAnnotations();
   BlockStmt body = decl.getBlock();
   StringBuilder sb = new StringBuilder("<init>(");
   AClass clazz = (AClass) elem;
   AMethod method;
   if (params != null) {
     for (Parameter param : params) {
       Type ptype = param.getType();
       sb.append(getJVML(ptype));
     }
   }
   sb.append(")V");
   method = clazz.methods.vivify(sb.toString());
   visitDecl(decl, method);
   if (params != null) {
     for (Parameter param : params) {
       AField field = method.parameters.vivify(i++);
       visitType(param.getType(), field.type);
     }
   }
   if (rcvrAnnos != null) {
     for (AnnotationExpr expr : rcvrAnnos) {
       Annotation anno = extractAnnotation(expr);
       method.receiver.tlAnnotationsHere.add(anno);
     }
   }
   return body == null ? null : body.accept(this, method);
   // return super.visit(decl, elem);
 }
  @Override
  public void visit(Parameter n, Object arg) {
    printAnnotations(n.getAnnotations(), arg);
    printModifiers(n.getModifiers());

    n.getType().accept(this, arg);
    if (n.isVarArgs()) {
      printer.print("...");
    }
    printer.print(" ");
    n.getId().accept(this, arg);
  }
  @Override
  public void visit(MethodDeclaration n, Object arg) {
    printJavadoc(n.getJavaDoc(), arg);
    printMemberAnnotations(n.getAnnotations(), arg);
    printModifiers(n.getModifiers());

    printTypeParameters(n.getTypeParameters(), arg);
    if (n.getTypeParameters() != null) {
      printer.print(" ");
    }

    n.getType().accept(this, arg);
    printer.print(" ");
    printer.print(n.getName());

    printer.print("(");
    if (n.getParameters() != null) {
      for (Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
        Parameter p = i.next();
        p.accept(this, arg);
        if (i.hasNext()) {
          printer.print(", ");
        }
      }
    }
    printer.print(")");

    for (int i = 0; i < n.getArrayCount(); i++) {
      printer.print("[]");
    }

    printAnnotations(n.getReceiverAnnotations(), arg, true);

    if (n.getThrows() != null) {
      printer.print(" throws ");
      for (Iterator<NameExpr> i = n.getThrows().iterator(); i.hasNext(); ) {
        NameExpr name = i.next();
        name.accept(this, arg);
        if (i.hasNext()) {
          printer.print(", ");
        }
      }
    }
    if (n.getBody() == null) {
      printer.print(";");
    } else {
      printer.print(" ");
      n.getBody().accept(this, arg);
    }
  }
 @Override
 public Void visit(MethodDeclaration decl, AElement elem) {
   Type type = decl.getType();
   List<Parameter> params = decl.getParameters();
   List<TypeParameter> typeParams = decl.getTypeParameters();
   List<AnnotationExpr> rcvrAnnos = decl.getReceiverAnnotations();
   BlockStmt body = decl.getBody();
   StringBuilder sb = new StringBuilder(decl.getName()).append('(');
   AClass clazz = (AClass) elem;
   AMethod method;
   if (params != null) {
     for (Parameter param : params) {
       Type ptype = param.getType();
       sb.append(getJVML(ptype));
     }
   }
   sb.append(')').append(getJVML(type));
   method = clazz.methods.vivify(sb.toString());
   visitDecl(decl, method);
   visitType(type, method.returnType);
   if (params != null) {
     int i = 0;
     for (Parameter param : params) {
       AField field = method.parameters.vivify(i++);
       visitType(param.getType(), field.type);
     }
   }
   if (rcvrAnnos != null) {
     for (AnnotationExpr expr : rcvrAnnos) {
       Annotation anno = extractAnnotation(expr);
       method.receiver.type.tlAnnotationsHere.add(anno);
     }
   }
   if (typeParams != null) {
     int i = 0;
     for (TypeParameter typeParam : typeParams) {
       List<ClassOrInterfaceType> bounds = typeParam.getTypeBound();
       if (bounds != null) {
         int j = 0;
         for (ClassOrInterfaceType bound : bounds) {
           BoundLocation loc = new BoundLocation(i, j);
           bound.accept(this, method.bounds.vivify(loc));
           ++j;
         }
       }
       ++i;
     }
   }
   return body == null ? null : body.accept(this, method);
 }