package introspect;

import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.instrumentation.MethodDelegation;
import net.bytebuddy.instrumentation.SuperMethodCall;
import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;

public class IntrospectProfilingAgent {

  private static final Instrumentation instrumentation = ByteBuddyAgent.installOnOpenJDK();

  public static void initializeAgent(String name) {
    new AgentBuilder.Default()
      .rebase(ElementMatchers.nameContains(name)
              .and(ElementMatchers.nameContains("$"))
              .and(ElementMatchers.not(ElementMatchers.nameContains("load")))
              .and(ElementMatchers.not(ElementMatchers.nameContains("auto")))
              .and(ElementMatchers.not(ElementMatchers.nameContains("init"))))

      .transform(new AgentBuilder.Transformer() {
          @Override
            public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
                                                    TypeDescription typeDescription) {
            System.out.printf("Transforming %s\n", typeDescription.getName());
            return builder
              .method(ElementMatchers.named("invoke"))
              .intercept(MethodDelegation.to(Interceptor.class));
          }
        })
      .installOn(instrumentation);
  }

}

@@ -680,32 +680,35 @@
 e)%0A             
+ //
  .and(ElementMat
@@ -728,24 +728,110 @@
 tains(%22$%22))%0A
+              .and(ElementMatchers.not(ElementMatchers.nameContains(%22SomeProtocol%22)))%0A
             
@@ -1112,18 +1112,16 @@
         
-  
 @Overrid
@@ -1122,20 +1122,16 @@
 verride%0A
-    
         
@@ -1205,60 +1205,8 @@
 der,
-%0A                                                   
  Typ
@@ -1233,26 +1233,24 @@
 cription) %7B%0A
-  
           Sy
@@ -1328,80 +1328,523 @@
     
-  return builder%0A              .method(ElementMatchers.named(%22invoke%22))%0A
+System.out.printf(%22%25s, isinterface: %25s %5Cn%22, typeDescription, typeDescription.isInterface());%0A          if (!typeDescription.isInterface() && !typeDescription.isAbstract()) %7B%0A            return builder.method(ElementMatchers.not(ElementMatchers.nameContains(%22toString%22))%0A                                                 .and(ElementMatchers.not(ElementMatchers.nameContains(%22hashCode%22)))%0A                                                 .and(ElementMatchers.not(ElementMatchers.nameContains(%22equals%22))))%0A            
     
@@ -1901,24 +1901,71 @@
 or.class));%0A
+          %7D else %7B%0A            return builder;%0A
           %7D%0A
@@ -1964,18 +1964,26 @@
       %7D%0A
-
   
+      %7D%0A
       %7D)

Make calls non-recursive