// Path: src/main/java/instrumentj/ProbeExecutor.java
// public interface ProbeExecutor {
// 
//     public void objectAllocationProbes(String className);
// 
//     public void methodEntryProbes(String className, String methodName, String methodDescription, Object[] methodArgs);
// 
//     public void methodExitProbes(String className, String methodName, String methodDescription, int opcode);
// }
// 
// 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/ProfilerController.java
// public interface ProfilerController {
// 
//     /**
//      * Activates this {@code ProfileController}
//      * <p>
//      * {@code ProfileController}s that are active will perform bytecode
//      * instrumentation
//      */
//     public void activate();
// 
//     /**
//      * Deactivates this {@code ProfileController}
//      * <p>
//      * {@code ProfileController}s that are deactivated will not perform any work
//      */
//     public void deactivate();
// 
//     /**
//      * Returns an approximation of an object's size.
//      *
//      * @param objectToSize
//      *            the object to examine
//      * @return the approximate size of the object
//      *
//      * @see Instrumentation#getObjectSize(Object)
//      */
//     public long getObjectSize(final Object objectToSize);
// 
//     /**
//      * Determines whether or not this {@code ProfileController} is active
//      *
//      * @return true if active; false otherwise
//      */
//     public boolean isActive();
// }


import instrumentj.ProbeExecutor;
import instrumentj.ProbeManager;
import instrumentj.ProfilerController;
import java.lang.instrument.Instrumentation;
import java.util.concurrent.atomic.AtomicBoolean;
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
package instrumentj.impl;



/**
 * @author Stephen Evanchik (evanchsa@gmail.com)
 *
 */
public final class ProfilerControllerImpl implements ProfilerController {

    private final AtomicBoolean active = new AtomicBoolean(false);

    private final Instrumentation instrumentation;

    private final ProbeExecutor probeExecutor;

    private ProbeManagerImpl probeManagerImpl;

    /**
     *
     * @param instrumentation
     */
    public ProfilerControllerImpl(final Instrumentation instrumentation) {
        if (instrumentation == null) {
            throw new NullPointerException("instrumentation");
        }

        this.instrumentation = instrumentation;
        this.probeManagerImpl = new ProbeManagerImpl(instrumentation);
        this.probeExecutor = new ProbeExecutorImpl(probeManagerImpl);
    }

    @Override
    public void activate() {
        active.set(true);
    }

    @Override
    public void deactivate() {
        active.set(false);
    }

    @Override
    public long getObjectSize(final Object objectToSize) {
        return instrumentation.getObjectSize(objectToSize);
    }

// Path: src/main/java/instrumentj/ProbeExecutor.java
// public interface ProbeExecutor {
// 
//     public void objectAllocationProbes(String className);
// 
//     public void methodEntryProbes(String className, String methodName, String methodDescription, Object[] methodArgs);
// 
//     public void methodExitProbes(String className, String methodName, String methodDescription, int opcode);
// }
// 
// 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/ProfilerController.java
// public interface ProfilerController {
// 
//     /**
//      * Activates this {@code ProfileController}
//      * <p>
//      * {@code ProfileController}s that are active will perform bytecode
//      * instrumentation
//      */
//     public void activate();
// 
//     /**
//      * Deactivates this {@code ProfileController}
//      * <p>
//      * {@code ProfileController}s that are deactivated will not perform any work
//      */
//     public void deactivate();
// 
//     /**
//      * Returns an approximation of an object's size.
//      *
//      * @param objectToSize
//      *            the object to examine
//      * @return the approximate size of the object
//      *
//      * @see Instrumentation#getObjectSize(Object)
//      */
//     public long getObjectSize(final Object objectToSize);
// 
//     /**
//      * Determines whether or not this {@code ProfileController} is active
//      *
//      * @return true if active; false otherwise
//      */
//     public boolean isActive();
// }


// Path: src/main/java/instrumentj/impl/ProfilerControllerImpl.java
import instrumentj.ProbeExecutor;
import instrumentj.ProbeManager;
import instrumentj.ProfilerController;
import java.lang.instrument.Instrumentation;
import java.util.concurrent.atomic.AtomicBoolean;

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
package instrumentj.impl;



/**
 * @author Stephen Evanchik (evanchsa@gmail.com)
 *
 */
public final class ProfilerControllerImpl implements ProfilerController {

    private final AtomicBoolean active = new AtomicBoolean(false);

    private final Instrumentation instrumentation;

    private final ProbeExecutor probeExecutor;

    private ProbeManagerImpl probeManagerImpl;

    /**
     *
     * @param instrumentation
     */
    public ProfilerControllerImpl(final Instrumentation instrumentation) {
        if (instrumentation == null) {
            throw new NullPointerException("instrumentation");
        }

        this.instrumentation = instrumentation;
        this.probeManagerImpl = new ProbeManagerImpl(instrumentation);
        this.probeExecutor = new ProbeExecutorImpl(probeManagerImpl);
    }

    @Override
    public void activate() {
        active.set(true);
    }

    @Override
    public void deactivate() {
        active.set(false);
    }

    @Override
    public long getObjectSize(final Object objectToSize) {
        return instrumentation.getObjectSize(objectToSize);
    }

    public ProbeExecutor getProbeExecutor() {