/* NEST (New Scala Test)
 * Copyright 2007-2013 LAMP/EPFL
 * @author Grzegorz Kossakowski
 */

package scala.tools.partest.javaagent;

import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;

import scala.tools.asm.ClassReader;
import scala.tools.asm.ClassWriter;

public class ASMTransformer implements ClassFileTransformer {
  
  private boolean shouldTransform(String className) {
    return 
        // do not instrument instrumentation logic (in order to avoid infinite recursion)
        !className.startsWith("scala/tools/partest/instrumented/") &&
        !className.startsWith("scala/tools/partest/javaagent/") &&
        // we instrument all classes from empty package
        (!className.contains("/") ||
        // we instrument all classes from scala package
        className.startsWith("scala/") ||
        // we instrument all classes from `instrumented` package
        className.startsWith("instrumented/"));
  }
	
	public byte[] transform(final ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
	  if (shouldTransform(className)) {
  		ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
                        // this is copied verbatim from the superclass,
                        // except that we use the outer class loader
                        @Override protected String getCommonSuperClass(final String type1, final String type2) {
                            Class<?> c, d;
                            try {
                                c = Class.forName(type1.replace('/', '.'), false, classLoader);
                                d = Class.forName(type2.replace('/', '.'), false, classLoader);
                            } catch (Exception e) {
                                throw new RuntimeException(e.toString());
                            }
                            if (c.isAssignableFrom(d)) {
                                return type1;
                            }
                            if (d.isAssignableFrom(c)) {
                                return type2;
                            }
                            if (c.isInterface() || d.isInterface()) {
                                return "java/lang/Object";
                            } else {
                                do {
                                    c = c.getSuperclass();
                                } while (!c.isAssignableFrom(d));
                                return c.getName().replace('.', '/');
                            }
                        }
                    };
  		ProfilerVisitor visitor = new ProfilerVisitor(writer);
  		ClassReader reader = new ClassReader(classfileBuffer);
  		reader.accept(visitor, 0);
  		return writer.toByteArray();
	  } else {
	    return classfileBuffer;
	  }
	}
}

@@ -1161,20 +1161,21 @@
 ame)) %7B%0A
+%09  
   
-%09%09
 ClassWri
@@ -1260,34 +1260,17 @@
 MAXS) %7B%0A
-                  
+%09
       //
@@ -1315,34 +1315,17 @@
 rclass,%0A
-                  
+%09
       //
@@ -1367,34 +1367,17 @@
  loader%0A
-                  
+%09
       @O
@@ -1463,36 +1463,17 @@
 ype2) %7B%0A
-                    
+%09
         
@@ -1491,64 +1491,24 @@
  d;%0A
-                            try %7B%0A                      
+%09        try %7B%0A%09
     
@@ -1573,37 +1573,25 @@
 assLoader);%0A
-             
+%09
             
@@ -1588,25 +1588,16 @@
         
-         
 d = Clas
@@ -1652,36 +1652,17 @@
 oader);%0A
-                    
+%09
         
@@ -1685,38 +1685,17 @@
 on e) %7B%0A
-                      
+%09
         
@@ -1742,59 +1742,28 @@
 ));%0A
-                            %7D%0A             
+%09        %7D%0A%09
         
     
@@ -1750,39 +1750,32 @@
      %7D%0A%09        
-       
 if (c.isAssignab
@@ -1787,38 +1787,17 @@
 m(d)) %7B%0A
-                      
+%09
         
@@ -1816,58 +1816,20 @@
 e1;%0A
-                            %7D%0A                    
+%09        %7D%0A%09
     
@@ -1861,38 +1861,17 @@
 m(c)) %7B%0A
-                      
+%09
         
@@ -1890,58 +1890,20 @@
 e2;%0A
-                            %7D%0A                    
+%09        %7D%0A%09
     
@@ -1948,38 +1948,17 @@
 ce()) %7B%0A
-                      
+%09
         
@@ -1986,38 +1986,25 @@
 bject%22;%0A
-              
+%09
         
       %7D 
@@ -1995,22 +1995,16 @@
         
-      
 %7D else %7B
@@ -2008,69 +2008,25 @@
 e %7B%0A
-                                do %7B%0A                        
+%09          do %7B%0A%09
     
@@ -2056,31 +2056,17 @@
 lass();%0A
-               
+%09
         
@@ -2067,23 +2067,16 @@
         
-       
 %7D while 
@@ -2101,38 +2101,17 @@
 om(d));%0A
-                      
+%09
         
@@ -2154,80 +2154,29 @@
 ');%0A
-                            %7D%0A                        %7D%0A                
+%09        %7D%0A%09      %7D%0A%09
     

Correct whitespace in `ASMTransformer.java`.