// Path: src/main/java/instrumentj/ProbeManager.java
// public interface ProbeManager {
// 
//     /**
//      * Adds the given {@link Probe}
//      *
//      * @param probe
//      *            the {@code Probe} to add
//      */
//     public void addProbe(Probe probe);
// 
//     /**
//      * Redefines the {@link Class} so that it has the required instrumentation
//      *
//      * @param clazz
//      *            the {@code Class} to redefine
//      * @return true if successfully instrumented; false otherwise
//      */
//     public boolean defineProbes(Class<?> clazz);
// 
//     /**
//      * Removes the given {@link Probe}
//      *
//      * @param probe
//      *            the {@code Probe} to remove
//      * @return true if removed; false otherwise
//      */
//     public boolean removeProbe(Probe probe);
// }
// 
// Path: src/main/java/instrumentj/probes/MethodEntryProbe.java
// public interface MethodEntryProbe extends MethodProbe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/MethodExitProbe.java
// public interface MethodExitProbe extends MethodProbe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/MethodProbe.java
// public interface MethodProbe extends Probe {
// 
//     /**
//      * Returns a filter that matches the method name that this {@code Probe}
//      * should execute against
//      *
//      * @return methodNameFilter
//      */
//    public String getMethodNameFilter();
// 
//     /**
//      * Returns a filter that matches the method's description (e.g. its
//      * arguments, return type etc.) that this {@code Probe} executes against
//      *
//      * @return methodDescriptionFilter
//      */
//    public String getMethodDescriptionFilter();
// }
// 
// Path: src/main/java/instrumentj/probes/MonitorProbe.java
// public interface MonitorProbe extends Probe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/ObjectAllocationProbe.java
// public interface ObjectAllocationProbe extends Probe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/Probe.java
// public interface Probe {
// 
//     public static final String WILDCARD = "*";
// 
//     /**
//      * Returns the filter that matches the class name or names that this
//      * {@code Probe} should respond to
//      *
//      * @return classNameFilter
//      */
//     public String getClassNameFilter();
// 
//     /**
//      * Executes this probe
//      *
//      * @param args
//      *            the arguments for this probe
//      */
//     public void run(Object... args);
// }


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import instrumentj.ProbeManager;
import instrumentj.probes.MethodEntryProbe;
import instrumentj.probes.MethodExitProbe;
import instrumentj.probes.MethodProbe;
import instrumentj.probes.MonitorProbe;
import instrumentj.probes.ObjectAllocationProbe;
import instrumentj.probes.Probe;
import java.lang.instrument.Instrumentation;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

            final String key = generateCombinedKey(classNameFilter, methodNameFilter);

            final List<T> methodProbeList = new CopyOnWriteArrayList<T>();
            if (probes.putIfAbsent(key, methodProbeList) == null) {
                methodProbeList.add(probe);
            } else {
                probes.get(key).add(probe);
            }
        }

        /**
         *
         * @param key
         * @return
         */
        public Collection<T> get(final String classNameFilter, final String methodNameFilter) {
            final String key;
            if ("<init>".equals(methodNameFilter)) {
                /*
                 *  Don't generate the suffixes for the "<init>"
                 *  because the token is not divisible unlike
                 *  method names
                 */
                key = generateCombinedKey(classNameFilter, "");
            } else {
                key = generateCombinedKey(classNameFilter, methodNameFilter);
            }

            final Set<T> values = new LinkedHashSet<T>();
// Path: src/main/java/instrumentj/ProbeManager.java
// public interface ProbeManager {
// 
//     /**
//      * Adds the given {@link Probe}
//      *
//      * @param probe
//      *            the {@code Probe} to add
//      */
//     public void addProbe(Probe probe);
// 
//     /**
//      * Redefines the {@link Class} so that it has the required instrumentation
//      *
//      * @param clazz
//      *            the {@code Class} to redefine
//      * @return true if successfully instrumented; false otherwise
//      */
//     public boolean defineProbes(Class<?> clazz);
// 
//     /**
//      * Removes the given {@link Probe}
//      *
//      * @param probe
//      *            the {@code Probe} to remove
//      * @return true if removed; false otherwise
//      */
//     public boolean removeProbe(Probe probe);
// }
// 
// Path: src/main/java/instrumentj/probes/MethodEntryProbe.java
// public interface MethodEntryProbe extends MethodProbe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/MethodExitProbe.java
// public interface MethodExitProbe extends MethodProbe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/MethodProbe.java
// public interface MethodProbe extends Probe {
// 
//     /**
//      * Returns a filter that matches the method name that this {@code Probe}
//      * should execute against
//      *
//      * @return methodNameFilter
//      */
//    public String getMethodNameFilter();
// 
//     /**
//      * Returns a filter that matches the method's description (e.g. its
//      * arguments, return type etc.) that this {@code Probe} executes against
//      *
//      * @return methodDescriptionFilter
//      */
//    public String getMethodDescriptionFilter();
// }
// 
// Path: src/main/java/instrumentj/probes/MonitorProbe.java
// public interface MonitorProbe extends Probe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/ObjectAllocationProbe.java
// public interface ObjectAllocationProbe extends Probe {
// 
// }
// 
// Path: src/main/java/instrumentj/probes/Probe.java
// public interface Probe {
// 
//     public static final String WILDCARD = "*";
// 
//     /**
//      * Returns the filter that matches the class name or names that this
//      * {@code Probe} should respond to
//      *
//      * @return classNameFilter
//      */
//     public String getClassNameFilter();
// 
//     /**
//      * Executes this probe
//      *
//      * @param args
//      *            the arguments for this probe
//      */
//     public void run(Object... args);
// }


// Path: src/main/java/instrumentj/impl/ProbeManagerImpl.java
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import instrumentj.ProbeManager;
import instrumentj.probes.MethodEntryProbe;
import instrumentj.probes.MethodExitProbe;
import instrumentj.probes.MethodProbe;
import instrumentj.probes.MonitorProbe;
import instrumentj.probes.ObjectAllocationProbe;
import instrumentj.probes.Probe;
import java.lang.instrument.Instrumentation;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;


            final String key = generateCombinedKey(classNameFilter, methodNameFilter);

            final List<T> methodProbeList = new CopyOnWriteArrayList<T>();
            if (probes.putIfAbsent(key, methodProbeList) == null) {
                methodProbeList.add(probe);
            } else {
                probes.get(key).add(probe);
            }
        }

        /**
         *
         * @param key
         * @return
         */
        public Collection<T> get(final String classNameFilter, final String methodNameFilter) {
            final String key;
            if ("<init>".equals(methodNameFilter)) {
                /*
                 *  Don't generate the suffixes for the "<init>"
                 *  because the token is not divisible unlike
                 *  method names
                 */
                key = generateCombinedKey(classNameFilter, "");
            } else {
                key = generateCombinedKey(classNameFilter, methodNameFilter);
            }

            final Set<T> values = new LinkedHashSet<T>();
            values.addAll(classWildCards);