// Path: ProfileData/src/main/java/net/jproffa/profiledata/ThreadBlocker.java
// public final class ThreadBlocker {
//     // ThreadBlockerTransformer in the main project injects Thread
//     // with code that calls {checkStartingThreadAllowed().
//     
//     private ThreadBlocker() {
//     }
//     
//     public static interface Policy {
//         public boolean isAllowedToStart(Thread thread);
//     }
//     
//     private static final List<Policy> policies = new ArrayList<Policy>();
// 
//     public static synchronized void addPolicy(Policy cb) {
//         policies.add(cb);
//     }
// 
//     public static synchronized void removePolicy(Policy cb) {
//         policies.remove(cb);
//     }
// 
//     public static synchronized boolean isStartingThreadAllowed(Thread thread) {
//         for (Policy cb : policies) {
//             if (!cb.isAllowedToStart(thread)) {
//                 return false;
//             }
//         }
//         return true;
//     }
// 
//     public static void checkStartingThreadAllowed(Thread thread) {
//         if (!isStartingThreadAllowed(thread)) {
//             throw new IllegalStateException("Starting thread " + thread.getName() + " denied due to profiling.");
//         }
//     }
// }


import net.jproffa.profiledata.ThreadBlocker;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.List;
import org.apache.log4j.Logger;
import org.objectweb.asm.tree.*;
import static org.objectweb.asm.Opcodes.*;
    public byte[] transform(
            ClassLoader loader,
            String className,
            Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain,
            byte[] classfileBuffer) throws IllegalClassFormatException {
        try {
            if (!className.equals("java/lang/Thread")) {
                return null;
            }
            ClassNode thread = Util.initClassNode(classfileBuffer);

            InsnList insns = getInstructions();
            for (MethodNode methodNode : (List<MethodNode>) thread.methods) {
                if (!methodNode.name.equals("start")) {
                    continue;
                }
                methodNode.instructions.insert(insns);
            }
            Thread.currentThread().getStackTrace();
            return Util.generateBytecode(thread);
        } catch (Throwable t) {
            logger.fatal("Exception while transforming", t);
        }

        return null;
    }

    private InsnList getInstructions() {
        InsnList insnList = new InsnList();
// Path: ProfileData/src/main/java/net/jproffa/profiledata/ThreadBlocker.java
// public final class ThreadBlocker {
//     // ThreadBlockerTransformer in the main project injects Thread
//     // with code that calls {checkStartingThreadAllowed().
//     
//     private ThreadBlocker() {
//     }
//     
//     public static interface Policy {
//         public boolean isAllowedToStart(Thread thread);
//     }
//     
//     private static final List<Policy> policies = new ArrayList<Policy>();
// 
//     public static synchronized void addPolicy(Policy cb) {
//         policies.add(cb);
//     }
// 
//     public static synchronized void removePolicy(Policy cb) {
//         policies.remove(cb);
//     }
// 
//     public static synchronized boolean isStartingThreadAllowed(Thread thread) {
//         for (Policy cb : policies) {
//             if (!cb.isAllowedToStart(thread)) {
//                 return false;
//             }
//         }
//         return true;
//     }
// 
//     public static void checkStartingThreadAllowed(Thread thread) {
//         if (!isStartingThreadAllowed(thread)) {
//             throw new IllegalStateException("Starting thread " + thread.getName() + " denied due to profiling.");
//         }
//     }
// }


// Path: Profiler/src/main/java/net/jproffa/profiler/ThreadBlockerTransformer.java
import net.jproffa.profiledata.ThreadBlocker;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.List;
import org.apache.log4j.Logger;
import org.objectweb.asm.tree.*;
import static org.objectweb.asm.Opcodes.*;

    public byte[] transform(
            ClassLoader loader,
            String className,
            Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain,
            byte[] classfileBuffer) throws IllegalClassFormatException {
        try {
            if (!className.equals("java/lang/Thread")) {
                return null;
            }
            ClassNode thread = Util.initClassNode(classfileBuffer);

            InsnList insns = getInstructions();
            for (MethodNode methodNode : (List<MethodNode>) thread.methods) {
                if (!methodNode.name.equals("start")) {
                    continue;
                }
                methodNode.instructions.insert(insns);
            }
            Thread.currentThread().getStackTrace();
            return Util.generateBytecode(thread);
        } catch (Throwable t) {
            logger.fatal("Exception while transforming", t);
        }

        return null;
    }

    private InsnList getInstructions() {
        InsnList insnList = new InsnList();
        String className = ThreadBlocker.class.getName().replace('.', '/');