public void visit(
      final int version,
      final int access,
      final String name,
      final String signature,
      final String superName,
      final String[] interfaces) {
    int major = version & 0xFFFF;
    int minor = version >>> 16;
    buf.setLength(0);
    buf.append("// class version ")
        .append(major)
        .append('.')
        .append(minor)
        .append(" (")
        .append(version)
        .append(")\n");
    if ((access & Opcodes.ACC_DEPRECATED) != 0) {
      buf.append("// DEPRECATED\n");
    }
    buf.append("// access flags ").append(access).append('\n');

    appendDescriptor(CLASS_SIGNATURE, signature);
    if (signature != null) {
      TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
      SignatureReader r = new SignatureReader(signature);
      r.accept(sv);
      buf.append("// declaration: ").append(name).append(sv.getDeclaration()).append('\n');
    }

    appendAccess(access & ~Opcodes.ACC_SUPER);
    if ((access & Opcodes.ACC_ANNOTATION) != 0) {
      buf.append("@interface ");
    } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
      buf.append("interface ");
    } else if ((access & Opcodes.ACC_ENUM) == 0) {
      buf.append("class ");
    }
    appendDescriptor(INTERNAL_NAME, name);

    if (superName != null && !"java/lang/Object".equals(superName)) {
      buf.append(" extends ");
      appendDescriptor(INTERNAL_NAME, superName);
      buf.append(' ');
    }
    if (interfaces != null && interfaces.length > 0) {
      buf.append(" implements ");
      for (int i = 0; i < interfaces.length; ++i) {
        appendDescriptor(INTERNAL_NAME, interfaces[i]);
        buf.append(' ');
      }
    }
    buf.append(" {\n\n");

    text.add(buf.toString());

    if (cv != null) {
      cv.visit(version, access, name, signature, superName, interfaces);
    }
  }
  public FieldVisitor visitField(
      final int access,
      final String name,
      final String desc,
      final String signature,
      final Object value) {
    buf.setLength(0);
    buf.append('\n');
    if ((access & Opcodes.ACC_DEPRECATED) != 0) {
      buf.append(tab).append("// DEPRECATED\n");
    }
    buf.append(tab).append("// access flags ").append(access).append('\n');
    if (signature != null) {
      buf.append(tab);
      appendDescriptor(FIELD_SIGNATURE, signature);

      TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
      SignatureReader r = new SignatureReader(signature);
      r.acceptType(sv);
      buf.append(tab).append("// declaration: ").append(sv.getDeclaration()).append('\n');
    }

    buf.append(tab);
    appendAccess(access);

    appendDescriptor(FIELD_DESCRIPTOR, desc);
    buf.append(' ').append(name);
    if (value != null) {
      buf.append(" = ");
      if (value instanceof String) {
        buf.append('\"').append(value).append('\"');
      } else {
        buf.append(value);
      }
    }

    buf.append('\n');
    text.add(buf.toString());

    TraceFieldVisitor tav = createTraceFieldVisitor();
    text.add(tav.getText());

    if (cv != null) {
      tav.fv = cv.visitField(access, name, desc, signature, value);
    }

    return tav;
  }
  public MethodVisitor visitMethod(
      final int access,
      final String name,
      final String desc,
      final String signature,
      final String[] exceptions) {
    buf.setLength(0);
    buf.append('\n');
    if ((access & Opcodes.ACC_DEPRECATED) != 0) {
      buf.append(tab).append("// DEPRECATED\n");
    }
    buf.append(tab).append("// access flags ").append(access).append('\n');

    if (signature != null) {
      buf.append(tab);
      appendDescriptor(METHOD_SIGNATURE, signature);

      TraceSignatureVisitor v = new TraceSignatureVisitor(0);
      SignatureReader r = new SignatureReader(signature);
      r.accept(v);
      String genericDecl = v.getDeclaration();
      String genericReturn = v.getReturnType();
      String genericExceptions = v.getExceptions();

      buf.append(tab)
          .append("// declaration: ")
          .append(genericReturn)
          .append(' ')
          .append(name)
          .append(genericDecl);
      if (genericExceptions != null) {
        buf.append(" throws ").append(genericExceptions);
      }
      buf.append('\n');
    }

    buf.append(tab);
    appendAccess(access);
    if ((access & Opcodes.ACC_NATIVE) != 0) {
      buf.append("native ");
    }
    if ((access & Opcodes.ACC_VARARGS) != 0) {
      buf.append("varargs ");
    }
    if ((access & Opcodes.ACC_BRIDGE) != 0) {
      buf.append("bridge ");
    }

    buf.append(name);
    appendDescriptor(METHOD_DESCRIPTOR, desc);
    if (exceptions != null && exceptions.length > 0) {
      buf.append(" throws ");
      for (int i = 0; i < exceptions.length; ++i) {
        appendDescriptor(INTERNAL_NAME, exceptions[i]);
        buf.append(' ');
      }
    }

    buf.append('\n');
    text.add(buf.toString());

    TraceMethodVisitor tcv = createTraceMethodVisitor();
    text.add(tcv.getText());

    if (cv != null) {
      tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions);
    }

    return tcv;
  }