/*
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Copyright 2003 Wily Technology, Inc.
 */

#include    <jni.h>
#include    <jvmti.h>
#include    <stdlib.h>
#include    <string.h>
#include    "JPLISAgent.h"
#include    "JPLISAssert.h"
#include    "Utilities.h"
#include    "Reentrancy.h"
#include    "JavaExceptions.h"

#include    "EncodingSupport.h"
#include    "FileSystemSupport.h"    /* For MAXPATHLEN & uintptr_t */

#include    "sun_instrument_InstrumentationImpl.h"

/*
 *  The JPLISAgent manages the initialization all of the Java programming language Agents.
 *  It also supports the native method bridge between the JPLIS and the JVMTI.
 *  It maintains a single JVMTI Env that all JPL agents share.
 *  It parses command line requests and creates individual Java agents.
 */


/*
 *  private prototypes
 */

/* Allocates an unformatted JPLIS agent data structure. Returns NULL if allocation fails. */
JPLISAgent *
allocateJPLISAgent(jvmtiEnv *       jvmtiEnv);

/* Initializes an already-allocated JPLIS agent data structure. */
JPLISInitializationError
initializeJPLISAgent(   JPLISAgent *    agent,
                        JavaVM *        vm,
                        jvmtiEnv *      jvmtienv);
/* De-allocates a JPLIS agent data structure. Only used in partial-failure cases at startup;
 * in normal usage the JPLIS agent lives forever
 */
void
deallocateJPLISAgent(   jvmtiEnv *      jvmtienv,
                        JPLISAgent *    agent);

/* Does one-time work to interrogate the JVM about capabilities and cache the answers. */
void
checkCapabilities(JPLISAgent * agent);

/* Takes the elements of the command string (agent class name and options string) and
 * create java strings for them.
 * Returns true if a classname was found. Makes no promises beyond the textual; says nothing about whether
 * the class exists or can be loaded.
 * If return value is true, sets outputClassname to a non-NULL local JNI reference.
 * If return value is true, sets outputOptionsString either to NULL or to a non-NULL local JNI reference.
 * If return value is false, neither output parameter is set.
 */
jboolean
commandStringIntoJavaStrings(  JNIEnv *        jnienv,
                               const char *    classname,
                               const char *    optionsString,
                               jstring *       outputClassname,
                               jstring *       outputOptionsString);

/* Start one Java agent from the supplied parameters.
 * Most of the logic lives in a helper function that lives over in Java code--
 * we pass parameters out to Java and use our own Java helper to actually
 * load the agent and call the premain.
 * Returns true if the Java agent class is loaded and the premain/agentmain method completes
 * with no exceptions, false otherwise.
 */
jboolean
invokeJavaAgentMainMethod( JNIEnv *    jnienv,
                           jobject     instrumentationImpl,
                           jmethodID   agentMainMethod,
                           jstring     className,
                           jstring     optionsString);

/* Once we have loaded the Java agent and called the premain,
 * we can release the copies we have been keeping of the command line
 * data (agent class name and option strings).
 */
void
deallocateCommandLineData(JPLISAgent * agent);

/*
 *  Common support for various class list fetchers.
 */
typedef jvmtiError (*ClassListFetcher)
    (   jvmtiEnv *  jvmtiEnv,
        jobject     classLoader,
        jint *      classCount,
        jclass **   classes);

/* Fetcher that ignores the class loader parameter, and uses the JVMTI to get a list of all classes.
 * Returns a jvmtiError according to the underlying JVMTI service.
 */
jvmtiError
getAllLoadedClassesClassListFetcher(    jvmtiEnv *  jvmtiEnv,
                                        jobject     classLoader,
                                        jint *      classCount,
                                        jclass **   classes);

/* Fetcher that uses the class loader parameter, and uses the JVMTI to get a list of all classes
 * for which the supplied loader is the initiating loader.
 * Returns a jvmtiError according to the underlying JVMTI service.
 */
jvmtiError
getInitiatedClassesClassListFetcher(    jvmtiEnv *  jvmtiEnv,
                                        jobject     classLoader,
                                        jint *      classCount,
                                        jclass **   classes);

/*
 * Common guts for two native methods, which are the same except for the policy for fetching
 * the list of classes.
 * Either returns a local JNI reference to an array of references to java.lang.Class.
 * Can throw, if it does will alter the JNIEnv with an outstanding exception.
 */
jobjectArray
commonGetClassList( JNIEnv *            jnienv,
                    JPLISAgent *        agent,
                    jobject             classLoader,
                    ClassListFetcher    fetcher);


/*
 *  Misc. utilities.
 */

/* Checked exception mapper used by the redefine classes implementation.
 * Allows ClassNotFoundException or UnmodifiableClassException; maps others
 * to InternalError. Can return NULL in an error case.
 */
jthrowable
redefineClassMapper(    JNIEnv *    jnienv,
                        jthrowable  throwableToMap);

/* Turns a buffer of jclass * into a Java array whose elements are java.lang.Class.
 * Can throw, if it does will alter the JNIEnv with an outstanding exception.
 */
jobjectArray
getObjectArrayFromClasses(JNIEnv* jnienv, jclass* classes, jint classCount);


JPLISEnvironment *
getJPLISEnvironment(jvmtiEnv * jvmtienv) {
    JPLISEnvironment * environment  = NULL;
    jvmtiError         jvmtierror   = JVMTI_ERROR_NONE;

    jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
                                            jvmtienv,
                                            (void**)&environment);
    /* can be called from any phase */
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);

    if (jvmtierror == JVMTI_ERROR_NONE) {
        jplis_assert(environment != NULL);
        jplis_assert(environment->mJVMTIEnv == jvmtienv);
    } else {
        environment = NULL;
    }
    return environment;
}

/*
 *  OnLoad processing code.
 */

/*
 *  Creates a new JPLISAgent.
 *  Returns error if the agent cannot be created and initialized.
 *  The JPLISAgent* pointed to by agent_ptr is set to the new broker,
 *  or NULL if an error has occurred.
 */
JPLISInitializationError
createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
    JPLISInitializationError initerror       = JPLIS_INIT_ERROR_NONE;
    jvmtiEnv *               jvmtienv        = NULL;
    jint                     jnierror        = JNI_OK;

    *agent_ptr = NULL;
    jnierror = (*vm)->GetEnv(  vm,
                               (void **) &jvmtienv,
                               JVMTI_VERSION_1_1);
    if ( jnierror != JNI_OK ) {
        initerror = JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT;
    } else {
        JPLISAgent * agent = allocateJPLISAgent(jvmtienv);
        if ( agent == NULL ) {
            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
        } else {
            initerror = initializeJPLISAgent(  agent,
                                               vm,
                                               jvmtienv);
            if ( initerror == JPLIS_INIT_ERROR_NONE ) {
                *agent_ptr = agent;
            } else {
                deallocateJPLISAgent(jvmtienv, agent);
            }
        }

        /* don't leak envs */
        if ( initerror != JPLIS_INIT_ERROR_NONE ) {
            jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
            /* can be called from any phase */
            jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
        }
    }

    return initerror;
}

/*
 *  Allocates a JPLISAgent. Returns NULL if it cannot be allocated
 */
JPLISAgent *
allocateJPLISAgent(jvmtiEnv * jvmtienv) {
  return (JPLISAgent *) allocate( jvmtienv,
                                    sizeof(JPLISAgent));
}

JPLISInitializationError
initializeJPLISAgent(   JPLISAgent *    agent,
                        JavaVM *        vm,
                        jvmtiEnv *      jvmtienv) {
    jvmtiError      jvmtierror = JVMTI_ERROR_NONE;
    jvmtiPhase      phase;

    agent->mJVM                                      = vm;
    agent->mNormalEnvironment.mJVMTIEnv              = jvmtienv;
    agent->mNormalEnvironment.mAgent                 = agent;
    agent->mNormalEnvironment.mIsRetransformer       = JNI_FALSE;
    agent->mRetransformEnvironment.mJVMTIEnv         = NULL;        /* NULL until needed */
    agent->mRetransformEnvironment.mAgent            = agent;
    agent->mRetransformEnvironment.mIsRetransformer  = JNI_FALSE;   /* JNI_FALSE until mJVMTIEnv is set */
    agent->mAgentmainCaller                          = NULL;
    agent->mInstrumentationImpl                      = NULL;
    agent->mPremainCaller                            = NULL;
    agent->mTransform                                = NULL;
    agent->mRedefineAvailable                        = JNI_FALSE;   /* assume no for now */
    agent->mRedefineAdded                            = JNI_FALSE;
    agent->mNativeMethodPrefixAvailable              = JNI_FALSE;   /* assume no for now */
    agent->mNativeMethodPrefixAdded                  = JNI_FALSE;
    agent->mAgentClassName                           = NULL;
    agent->mOptionsString                            = NULL;

    /* make sure we can recover either handle in either direction.
     * the agent has a ref to the jvmti; make it mutual
     */
    jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
                                            jvmtienv,
                                            &(agent->mNormalEnvironment));
    /* can be called from any phase */
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);

    /* check what capabilities are available */
    checkCapabilities(agent);

    /* check phase - if live phase then we don't need the VMInit event */
    jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
    /* can be called from any phase */
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    if (phase == JVMTI_PHASE_LIVE) {
        return JPLIS_INIT_ERROR_NONE;
    }

    if (phase != JVMTI_PHASE_ONLOAD) {
        /* called too early or called too late; either way bail out */
        return JPLIS_INIT_ERROR_FAILURE;
    }

    /* now turn on the VMInit event */
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        jvmtiEventCallbacks callbacks;
        memset(&callbacks, 0, sizeof(callbacks));
        callbacks.VMInit = &eventHandlerVMInit;

        jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
                                                     &callbacks,
                                                     sizeof(callbacks));
        check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    }

    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
                                                jvmtienv,
                                                JVMTI_ENABLE,
                                                JVMTI_EVENT_VM_INIT,
                                                NULL /* all threads */);
        check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    }

    return (jvmtierror == JVMTI_ERROR_NONE)? JPLIS_INIT_ERROR_NONE : JPLIS_INIT_ERROR_FAILURE;
}

void
deallocateJPLISAgent(jvmtiEnv * jvmtienv, JPLISAgent * agent) {
    deallocate(jvmtienv, agent);
}


JPLISInitializationError
recordCommandLineData(  JPLISAgent *    agent,
                        const char *    agentClassName,
                        const char *    optionsString ) {
    JPLISInitializationError    initerror   = JPLIS_INIT_ERROR_NONE;
    char *      ourCopyOfAgentClassName     = NULL;
    char *      ourCopyOfOptionsString      = NULL;

    /* if no actual params, bail out now */
    if ((agentClassName == NULL) || (*agentClassName == 0)) {
        initerror = JPLIS_INIT_ERROR_AGENT_CLASS_NOT_SPECIFIED;
    } else {
        ourCopyOfAgentClassName = allocate(jvmti(agent), strlen(agentClassName)+1);
        if (ourCopyOfAgentClassName == NULL) {
            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
        } else {
            if (optionsString != NULL) {
                ourCopyOfOptionsString = allocate(jvmti(agent), strlen(optionsString)+1);
                if (ourCopyOfOptionsString == NULL) {
                    deallocate(jvmti(agent), ourCopyOfAgentClassName);
                    initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
                }
            }
        }
    }

    if (initerror == JPLIS_INIT_ERROR_NONE) {
        strcpy(ourCopyOfAgentClassName, agentClassName);
        if (optionsString != NULL) {
            strcpy(ourCopyOfOptionsString, optionsString);
        }
        agent->mAgentClassName = ourCopyOfAgentClassName;
        agent->mOptionsString = ourCopyOfOptionsString;
    }

    return initerror;
}

/*
 *  VMInit processing code.
 */


/*
 * If this call fails, the JVM launch will ultimately be aborted,
 * so we don't have to be super-careful to clean up in partial failure
 * cases.
 */
jboolean
processJavaStart(   JPLISAgent *    agent,
                    JNIEnv *        jnienv) {
    jboolean    result;

    /*
     *  OK, Java is up now. We can start everything that needs Java.
     */

    /*
     *  First make our emergency fallback InternalError throwable.
     */
    result = initializeFallbackError(jnienv);
    jplis_assert(result);

    /*
     *  Now make the InstrumentationImpl instance.
     */
    if ( result ) {
        result = createInstrumentationImpl(jnienv, agent);
        jplis_assert(result);
    }


    /*
     *  Then turn off the VMInit handler and turn on the ClassFileLoadHook.
     *  This way it is on before anyone registers a transformer.
     */
    if ( result ) {
        result = setLivePhaseEventHandlers(agent);
        jplis_assert(result);
    }

    /*
     *  Load the Java agent, and call the premain.
     */
    if ( result ) {
        result = startJavaAgent(agent, jnienv,
                                agent->mAgentClassName, agent->mOptionsString,
                                agent->mPremainCaller);
    }

    /*
     * Finally surrender all of the tracking data that we don't need any more.
     * If something is wrong, skip it, we will be aborting the JVM anyway.
     */
    if ( result ) {
        deallocateCommandLineData(agent);
    }

    return result;
}

jboolean
startJavaAgent( JPLISAgent *    agent,
                JNIEnv *        jnienv,
                const char *    classname,
                const char *    optionsString,
                jmethodID       agentMainMethod) {
    jboolean    success = JNI_FALSE;
    jstring classNameObject = NULL;
    jstring optionsStringObject = NULL;

    success = commandStringIntoJavaStrings(    jnienv,
                                               classname,
                                               optionsString,
                                               &classNameObject,
                                               &optionsStringObject);

    if (success) {
        success = invokeJavaAgentMainMethod(   jnienv,
                                               agent->mInstrumentationImpl,
                                               agentMainMethod,
                                               classNameObject,
                                               optionsStringObject);
    }

    return success;
}

void
deallocateCommandLineData( JPLISAgent * agent) {
    deallocate(jvmti(agent), (void*)agent->mAgentClassName);
    deallocate(jvmti(agent), (void*)agent->mOptionsString);

    /* zero things out so it is easier to see what is going on */
    agent->mAgentClassName = NULL;
    agent->mOptionsString = NULL;
}

/*
 * Create the java.lang.instrument.Instrumentation instance
 * and access information for it (method IDs, etc)
 */
jboolean
createInstrumentationImpl( JNIEnv *        jnienv,
                           JPLISAgent *    agent) {
    jclass      implClass               = NULL;
    jboolean    errorOutstanding        = JNI_FALSE;
    jobject     resultImpl              = NULL;
    jmethodID   premainCallerMethodID   = NULL;
    jmethodID   agentmainCallerMethodID = NULL;
    jmethodID   transformMethodID       = NULL;
    jmethodID   constructorID           = NULL;
    jobject     localReference          = NULL;

    /* First find the class of our implementation */
    implClass = (*jnienv)->FindClass(   jnienv,
                                        JPLIS_INSTRUMENTIMPL_CLASSNAME);
    errorOutstanding = checkForAndClearThrowable(jnienv);
    errorOutstanding = errorOutstanding || (implClass == NULL);
    jplis_assert_msg(!errorOutstanding, "find class on InstrumentationImpl failed");

    if ( !errorOutstanding ) {
        constructorID = (*jnienv)->GetMethodID( jnienv,
                                                implClass,
                                                JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODNAME,
                                                JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODSIGNATURE);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        errorOutstanding = errorOutstanding || (constructorID == NULL);
        jplis_assert_msg(!errorOutstanding, "find constructor on InstrumentationImpl failed");
        }

    if ( !errorOutstanding ) {
        jlong   peerReferenceAsScalar = (jlong)(intptr_t) agent;
        localReference = (*jnienv)->NewObject(  jnienv,
                                                implClass,
                                                constructorID,
                                                peerReferenceAsScalar,
                                                agent->mRedefineAdded,
                                                agent->mNativeMethodPrefixAdded);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        errorOutstanding = errorOutstanding || (localReference == NULL);
        jplis_assert_msg(!errorOutstanding, "call constructor on InstrumentationImpl failed");
    }

    if ( !errorOutstanding ) {
        resultImpl = (*jnienv)->NewGlobalRef(jnienv, localReference);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert_msg(!errorOutstanding, "copy local ref to global ref");
    }

    /* Now look up the method ID for the pre-main caller (we will need this more than once) */
    if ( !errorOutstanding ) {
        premainCallerMethodID = (*jnienv)->GetMethodID( jnienv,
                                                        implClass,
                                                        JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODNAME,
                                                        JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODSIGNATURE);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        errorOutstanding = errorOutstanding || (premainCallerMethodID == NULL);
        jplis_assert_msg(!errorOutstanding, "can't find premain invoker methodID");
    }

    /* Now look up the method ID for the agent-main caller */
    if ( !errorOutstanding ) {
        agentmainCallerMethodID = (*jnienv)->GetMethodID( jnienv,
                                                          implClass,
                                                          JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODNAME,
                                                          JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODSIGNATURE);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        errorOutstanding = errorOutstanding || (agentmainCallerMethodID == NULL);
        jplis_assert_msg(!errorOutstanding, "can't find agentmain invoker methodID");
    }

    /* Now look up the method ID for the transform method (we will need this constantly) */
    if ( !errorOutstanding ) {
        transformMethodID = (*jnienv)->GetMethodID( jnienv,
                                                    implClass,
                                                    JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODNAME,
                                                    JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODSIGNATURE);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        errorOutstanding = errorOutstanding || (transformMethodID == NULL);
        jplis_assert_msg(!errorOutstanding, "can't find transform methodID");
    }

    if ( !errorOutstanding ) {
        agent->mInstrumentationImpl = resultImpl;
        agent->mPremainCaller       = premainCallerMethodID;
        agent->mAgentmainCaller     = agentmainCallerMethodID;
        agent->mTransform           = transformMethodID;
    }

    return !errorOutstanding;
}

jboolean
commandStringIntoJavaStrings(  JNIEnv *        jnienv,
                               const char *    classname,
                               const char *    optionsString,
                               jstring *       outputClassname,
                               jstring *       outputOptionsString) {
    jstring     classnameJavaString     = NULL;
    jstring     optionsJavaString       = NULL;
    jboolean    errorOutstanding        = JNI_TRUE;

    classnameJavaString = (*jnienv)->NewStringUTF(jnienv, classname);
    errorOutstanding = checkForAndClearThrowable(jnienv);
    jplis_assert_msg(!errorOutstanding, "can't create class name java string");

    if ( !errorOutstanding ) {
        if ( optionsString != NULL) {
            optionsJavaString = (*jnienv)->NewStringUTF(jnienv, optionsString);
            errorOutstanding = checkForAndClearThrowable(jnienv);
            jplis_assert_msg(!errorOutstanding, "can't create options java string");
        }

        if ( !errorOutstanding ) {
            *outputClassname        = classnameJavaString;
            *outputOptionsString    = optionsJavaString;
        }
    }

    return !errorOutstanding;
}


jboolean
invokeJavaAgentMainMethod( JNIEnv *    jnienv,
                           jobject     instrumentationImpl,
                           jmethodID   mainCallingMethod,
                           jstring     className,
                           jstring     optionsString) {
    jboolean errorOutstanding = JNI_FALSE;

    jplis_assert(mainCallingMethod != NULL);
    if ( mainCallingMethod != NULL ) {
        (*jnienv)->CallVoidMethod(  jnienv,
                                    instrumentationImpl,
                                    mainCallingMethod,
                                    className,
                                    optionsString);
        errorOutstanding = checkForThrowable(jnienv);
        if ( errorOutstanding ) {
            logThrowable(jnienv);
        }
        checkForAndClearThrowable(jnienv);
    }
    return !errorOutstanding;
}

jboolean
setLivePhaseEventHandlers(  JPLISAgent * agent) {
    jvmtiEventCallbacks callbacks;
    jvmtiEnv *          jvmtienv = jvmti(agent);
    jvmtiError          jvmtierror;

    /* first swap out the handlers (switch from the VMInit handler, which we do not need,
     * to the ClassFileLoadHook handler, which is what the agents need from now on)
     */
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.ClassFileLoadHook = &eventHandlerClassFileLoadHook;

    jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
                                                 &callbacks,
                                                 sizeof(callbacks));
    check_phase_ret_false(jvmtierror);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);


    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        /* turn off VMInit */
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
                                                    jvmtienv,
                                                    JVMTI_DISABLE,
                                                    JVMTI_EVENT_VM_INIT,
                                                    NULL /* all threads */);
        check_phase_ret_false(jvmtierror);
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    }

    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        /* turn on ClassFileLoadHook */
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
                                                    jvmtienv,
                                                    JVMTI_ENABLE,
                                                    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
                                                    NULL /* all threads */);
        check_phase_ret_false(jvmtierror);
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    }

    return (jvmtierror == JVMTI_ERROR_NONE);
}

/**
 *  Check if the can_redefine_classes capability is available.
 */
void
checkCapabilities(JPLISAgent * agent) {
    jvmtiEnv *          jvmtienv = jvmti(agent);
    jvmtiCapabilities   potentialCapabilities;
    jvmtiError          jvmtierror;

    memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));

    jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
    check_phase_ret(jvmtierror);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);

    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        if ( potentialCapabilities.can_redefine_classes == 1 ) {
            agent->mRedefineAvailable = JNI_TRUE;
        }
        if ( potentialCapabilities.can_set_native_method_prefix == 1 ) {
            agent->mNativeMethodPrefixAvailable = JNI_TRUE;
        }
    }
}

/**
 * Enable native method prefix in one JVM TI environment
 */
void
enableNativeMethodPrefixCapability(jvmtiEnv * jvmtienv) {
    jvmtiCapabilities   desiredCapabilities;
    jvmtiError          jvmtierror;

        jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
        /* can be called from any phase */
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
        desiredCapabilities.can_set_native_method_prefix = 1;
        jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
        check_phase_ret(jvmtierror);
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}


/**
 * Add the can_set_native_method_prefix capability
 */
void
addNativeMethodPrefixCapability(JPLISAgent * agent) {
    if (agent->mNativeMethodPrefixAvailable && !agent->mNativeMethodPrefixAdded) {
        jvmtiEnv * jvmtienv = agent->mNormalEnvironment.mJVMTIEnv;
        enableNativeMethodPrefixCapability(jvmtienv);

        jvmtienv = agent->mRetransformEnvironment.mJVMTIEnv;
        if (jvmtienv != NULL) {
            enableNativeMethodPrefixCapability(jvmtienv);
        }
        agent->mNativeMethodPrefixAdded = JNI_TRUE;
    }
}

/**
 * Add the can_maintain_original_method_order capability (for testing)
 */
void
addOriginalMethodOrderCapability(JPLISAgent * agent) {
    jvmtiEnv *          jvmtienv = jvmti(agent);
    jvmtiCapabilities   desiredCapabilities;
    jvmtiError          jvmtierror;

    jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
    /* can be called from any phase */
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    desiredCapabilities.can_maintain_original_method_order = 1;
    jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
    check_phase_ret(jvmtierror);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}

/**
 * Add the can_redefine_classes capability
 */
void
addRedefineClassesCapability(JPLISAgent * agent) {
    jvmtiEnv *          jvmtienv = jvmti(agent);
    jvmtiCapabilities   desiredCapabilities;
    jvmtiError          jvmtierror;

    if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
        jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
        /* can be called from any phase */
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
        desiredCapabilities.can_redefine_classes = 1;
        jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
        check_phase_ret(jvmtierror);

        /*
         * With mixed premain/agentmain agents then it's possible that the
         * capability was potentially available in the onload phase but
         * subsequently unavailable in the live phase.
         */
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE ||
                     jvmtierror == JVMTI_ERROR_NOT_AVAILABLE);
        if (jvmtierror == JVMTI_ERROR_NONE) {
            agent->mRedefineAdded = JNI_TRUE;
        }
    }
}


/*
 *  Support for the JVMTI callbacks
 */

void
transformClassFile(             JPLISAgent *            agent,
                                JNIEnv *                jnienv,
                                jobject                 loaderObject,
                                const char*             name,
                                jclass                  classBeingRedefined,
                                jobject                 protectionDomain,
                                jint                    class_data_len,
                                const unsigned char*    class_data,
                                jint*                   new_class_data_len,
                                unsigned char**         new_class_data,
                                jboolean                is_retransformer) {
    jboolean        errorOutstanding        = JNI_FALSE;
    jstring         classNameStringObject   = NULL;
    jarray          classFileBufferObject   = NULL;
    jarray          transformedBufferObject = NULL;
    jsize           transformedBufferSize   = 0;
    unsigned char * resultBuffer            = NULL;
    jboolean        shouldRun               = JNI_FALSE;

    /* only do this if we aren't already in the middle of processing a class on this thread */
    shouldRun = tryToAcquireReentrancyToken(
                                jvmti(agent),
                                NULL);  /* this thread */

    if ( shouldRun ) {
        /* first marshall all the parameters */
        classNameStringObject = (*jnienv)->NewStringUTF(jnienv,
                                                        name);
        errorOutstanding = checkForAndClearThrowable(jnienv);
        jplis_assert_msg(!errorOutstanding, "can't create name string");

        if ( !errorOutstanding ) {
            classFileBufferObject = (*jnienv)->NewByteArray(jnienv,
                                                            class_data_len);
            errorOutstanding = checkForAndClearThrowable(jnienv);
            jplis_assert_msg(!errorOutstanding, "can't create byte arrau");
        }

        if ( !errorOutstanding ) {
            jbyte * typedBuffer = (jbyte *) class_data; /* nasty cast, dumb JNI interface, const missing */
                                                        /* The sign cast is safe. The const cast is dumb. */
            (*jnienv)->SetByteArrayRegion(  jnienv,
                                            classFileBufferObject,
                                            0,
                                            class_data_len,
                                            typedBuffer);
            errorOutstanding = checkForAndClearThrowable(jnienv);
            jplis_assert_msg(!errorOutstanding, "can't set byte array region");
        }

        /*  now call the JPL agents to do the transforming */
        /*  potential future optimization: may want to skip this if there are none */
        if ( !errorOutstanding ) {
            jplis_assert(agent->mInstrumentationImpl != NULL);
            jplis_assert(agent->mTransform != NULL);
            transformedBufferObject = (*jnienv)->CallObjectMethod(
                                                jnienv,
                                                agent->mInstrumentationImpl,
                                                agent->mTransform,
                                                loaderObject,
                                                classNameStringObject,
                                                classBeingRedefined,
                                                protectionDomain,
                                                classFileBufferObject,
                                                is_retransformer);
            errorOutstanding = checkForAndClearThrowable(jnienv);
            jplis_assert_msg(!errorOutstanding, "transform method call failed");
        }

        /* Finally, unmarshall the parameters (if someone touched the buffer, tell the JVM) */
        if ( !errorOutstanding ) {
            if ( transformedBufferObject != NULL ) {
                transformedBufferSize = (*jnienv)->GetArrayLength(  jnienv,
                                                                    transformedBufferObject);
                errorOutstanding = checkForAndClearThrowable(jnienv);
                jplis_assert_msg(!errorOutstanding, "can't get array length");

                if ( !errorOutstanding ) {
                    /* allocate the response buffer with the JVMTI allocate call.
                     *  This is what the JVMTI spec says to do for Class File Load hook responses
                     */
                    jvmtiError  allocError = (*(jvmti(agent)))->Allocate(jvmti(agent),
                                                                             transformedBufferSize,
                                                                             &resultBuffer);
                    errorOutstanding = (allocError != JVMTI_ERROR_NONE);
                    jplis_assert_msg(!errorOutstanding, "can't allocate result buffer");
                }

                if ( !errorOutstanding ) {
                    (*jnienv)->GetByteArrayRegion(  jnienv,
                                                    transformedBufferObject,
                                                    0,
                                                    transformedBufferSize,
                                                    (jbyte *) resultBuffer);
                    errorOutstanding = checkForAndClearThrowable(jnienv);
                    jplis_assert_msg(!errorOutstanding, "can't get byte array region");

                    /* in this case, we will not return the buffer to the JVMTI,
                     * so we need to deallocate it ourselves
                     */
                    if ( errorOutstanding ) {
                        deallocate( jvmti(agent),
                                   (void*)resultBuffer);
                    }
                }

                if ( !errorOutstanding ) {
                    *new_class_data_len = (transformedBufferSize);
                    *new_class_data     = resultBuffer;
                }
            }
        }

        /* release the token */
        releaseReentrancyToken( jvmti(agent),
                                NULL);      /* this thread */

    }

    return;
}

/*
 *  Misc. internal utilities.
 */

/*
 *  The only checked exceptions we can throw are ClassNotFoundException and
 *  UnmodifiableClassException. All others map to InternalError.
 */
jthrowable
redefineClassMapper(    JNIEnv *    jnienv,
                        jthrowable  throwableToMap) {
    jthrowable  mappedThrowable = NULL;

    jplis_assert(isSafeForJNICalls(jnienv));
    jplis_assert(!isUnchecked(jnienv, throwableToMap));

    if ( isInstanceofClassName( jnienv,
                                throwableToMap,
                                "java/lang/ClassNotFoundException") ) {
        mappedThrowable = throwableToMap;
    } else {
        if ( isInstanceofClassName( jnienv,
                                throwableToMap,
                                "java/lang/instrument/UnmodifiableClassException")) {
            mappedThrowable = throwableToMap;
        } else {
            jstring message = NULL;

            message = getMessageFromThrowable(jnienv, throwableToMap);
            mappedThrowable = createInternalError(jnienv, message);
        }
    }

    jplis_assert(isSafeForJNICalls(jnienv));
    return mappedThrowable;
}

jobjectArray
getObjectArrayFromClasses(JNIEnv* jnienv, jclass* classes, jint classCount) {
    jclass          classArrayClass = NULL;
    jobjectArray    localArray      = NULL;
    jint            classIndex      = 0;
    jboolean        errorOccurred   = JNI_FALSE;

    /* get the class array class */
    classArrayClass = (*jnienv)->FindClass(jnienv, "java/lang/Class");
    errorOccurred = checkForThrowable(jnienv);

    if (!errorOccurred) {
        jplis_assert_msg(classArrayClass != NULL, "FindClass returned null class");

        /* create the array for the classes */
        localArray = (*jnienv)->NewObjectArray(jnienv, classCount, classArrayClass, NULL);
        errorOccurred = checkForThrowable(jnienv);

        if (!errorOccurred) {
            jplis_assert_msg(localArray != NULL, "NewObjectArray returned null array");

            /* now copy refs to all the classes and put them into the array */
            for (classIndex = 0; classIndex < classCount; classIndex++) {
                /* put class into array */
                (*jnienv)->SetObjectArrayElement(jnienv, localArray, classIndex, classes[classIndex]);
                errorOccurred = checkForThrowable(jnienv);

                if (errorOccurred) {
                    localArray = NULL;
                    break;
                }
            }
        }
    }

    return localArray;
}


/* Return the environment with the retransformation capability.
 * Create it if it doesn't exist.
 * Return NULL if it can't be created.
 */
jvmtiEnv *
retransformableEnvironment(JPLISAgent * agent) {
    jvmtiEnv *          retransformerEnv     = NULL;
    jint                jnierror             = JNI_OK;
    jvmtiCapabilities   desiredCapabilities;
    jvmtiEventCallbacks callbacks;
    jvmtiError          jvmtierror;

    if (agent->mRetransformEnvironment.mJVMTIEnv != NULL) {
        return agent->mRetransformEnvironment.mJVMTIEnv;
    }
    jnierror = (*agent->mJVM)->GetEnv(  agent->mJVM,
                               (void **) &retransformerEnv,
                               JVMTI_VERSION_1_1);
    if ( jnierror != JNI_OK ) {
        return NULL;
    }
    jvmtierror = (*retransformerEnv)->GetCapabilities(retransformerEnv, &desiredCapabilities);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    desiredCapabilities.can_retransform_classes = 1;
    if (agent->mNativeMethodPrefixAdded) {
        desiredCapabilities.can_set_native_method_prefix = 1;
    }

    jvmtierror = (*retransformerEnv)->AddCapabilities(retransformerEnv, &desiredCapabilities);
    if (jvmtierror != JVMTI_ERROR_NONE) {
         /* cannot get the capability, dispose of the retransforming environment */
        jvmtierror = (*retransformerEnv)->DisposeEnvironment(retransformerEnv);
        jplis_assert(jvmtierror == JVMTI_ERROR_NOT_AVAILABLE);
        return NULL;
    }
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.ClassFileLoadHook = &eventHandlerClassFileLoadHook;

    jvmtierror = (*retransformerEnv)->SetEventCallbacks(retransformerEnv,
                                                        &callbacks,
                                                        sizeof(callbacks));
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    if (jvmtierror == JVMTI_ERROR_NONE) {
        // install the retransforming environment
        agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv;
        agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;

        // Make it for ClassFileLoadHook handling
        jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage(
                                                       retransformerEnv,
                                                       &(agent->mRetransformEnvironment));
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
        if (jvmtierror == JVMTI_ERROR_NONE) {
            return retransformerEnv;
        }
    }
    return NULL;
}


/*
 *  Underpinnings for native methods
 */

jboolean
isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
    jvmtiEnv *          jvmtienv = jvmti(agent);
    jvmtiError          jvmtierror;
    jboolean            is_modifiable = JNI_FALSE;

    jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
                                                 clazz,
                                                 &is_modifiable);
    check_phase_ret_false(jvmtierror);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);

    return is_modifiable;
}

jboolean
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
    return agent->mRetransformEnvironment.mIsRetransformer;
}

void
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
    jvmtiEnv *          retransformerEnv     = retransformableEnvironment(agent);
    jvmtiError          jvmtierror;

    jplis_assert(retransformerEnv != NULL);
    jvmtierror = (*retransformerEnv)->SetEventNotificationMode(
                                                    retransformerEnv,
                                                    has? JVMTI_ENABLE : JVMTI_DISABLE,
                                                    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
                                                    NULL /* all threads */);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}

void
retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
    jvmtiEnv *  retransformerEnv     = retransformableEnvironment(agent);
    jboolean    errorOccurred        = JNI_FALSE;
    jvmtiError  errorCode            = JVMTI_ERROR_NONE;
    jsize       numClasses           = 0;
    jclass *    classArray           = NULL;

    /* This is supposed to be checked by caller, but just to be sure */
    if (retransformerEnv == NULL) {
        jplis_assert(retransformerEnv != NULL);
        errorOccurred = JNI_TRUE;
        errorCode = JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
    }

    /* This was supposed to be checked by caller too */
    if (!errorOccurred && classes == NULL) {
        jplis_assert(classes != NULL);
        errorOccurred = JNI_TRUE;
        errorCode = JVMTI_ERROR_NULL_POINTER;
    }

    if (!errorOccurred) {
        numClasses = (*jnienv)->GetArrayLength(jnienv, classes);
        errorOccurred = checkForThrowable(jnienv);
        jplis_assert(!errorOccurred);

        if (!errorOccurred && numClasses == 0) {
            jplis_assert(numClasses != 0);
            errorOccurred = JNI_TRUE;
            errorCode = JVMTI_ERROR_NULL_POINTER;
        }
    }

    if (!errorOccurred) {
        classArray = (jclass *) allocate(retransformerEnv,
                                         numClasses * sizeof(jclass));
        errorOccurred = (classArray == NULL);
        jplis_assert(!errorOccurred);
        if (errorOccurred) {
            errorCode = JVMTI_ERROR_OUT_OF_MEMORY;
        }
    }

    if (!errorOccurred) {
        jint index;
        for (index = 0; index < numClasses; index++) {
            classArray[index] = (*jnienv)->GetObjectArrayElement(jnienv, classes, index);
            errorOccurred = checkForThrowable(jnienv);
            jplis_assert(!errorOccurred);
            if (errorOccurred) {
                break;
            }

            if (classArray[index] == NULL) {
                jplis_assert(classArray[index] != NULL);
                errorOccurred = JNI_TRUE;
                errorCode = JVMTI_ERROR_NULL_POINTER;
                break;
            }
        }
    }

    if (!errorOccurred) {
        errorCode = (*retransformerEnv)->RetransformClasses(retransformerEnv,
                                                            numClasses, classArray);
        errorOccurred = (errorCode != JVMTI_ERROR_NONE);
    }

    /* Give back the buffer if we allocated it.  Throw any exceptions after.
     */
    if (classArray != NULL) {
        deallocate(retransformerEnv, (void*)classArray);
    }

    if (errorCode != JVMTI_ERROR_NONE) {
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
    }

    mapThrownThrowableIfNecessary(jnienv, redefineClassMapper);
}

/*
 *  Java code must not call this with a null list or a zero-length list.
 */
void
redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions) {
    jvmtiEnv*   jvmtienv                        = jvmti(agent);
    jboolean    errorOccurred                   = JNI_FALSE;
    jclass      classDefClass                   = NULL;
    jmethodID   getDefinitionClassMethodID      = NULL;
    jmethodID   getDefinitionClassFileMethodID  = NULL;
    jvmtiClassDefinition* classDefs             = NULL;
    jbyteArray* targetFiles                     = NULL;
    jsize       numDefs                         = 0;

    jplis_assert(classDefinitions != NULL);

    numDefs = (*jnienv)->GetArrayLength(jnienv, classDefinitions);
    errorOccurred = checkForThrowable(jnienv);
    jplis_assert(!errorOccurred);

    if (!errorOccurred) {
        jplis_assert(numDefs > 0);
        /* get method IDs for methods to call on class definitions */
        classDefClass = (*jnienv)->FindClass(jnienv, "java/lang/instrument/ClassDefinition");
        errorOccurred = checkForThrowable(jnienv);
        jplis_assert(!errorOccurred);
    }

    if (!errorOccurred) {
        getDefinitionClassMethodID = (*jnienv)->GetMethodID(    jnienv,
                                                classDefClass,
                                                "getDefinitionClass",
                                                "()Ljava/lang/Class;");
        errorOccurred = checkForThrowable(jnienv);
        jplis_assert(!errorOccurred);
    }

    if (!errorOccurred) {
        getDefinitionClassFileMethodID = (*jnienv)->GetMethodID(    jnienv,
                                                    classDefClass,
                                                    "getDefinitionClassFile",
                                                    "()[B");
        errorOccurred = checkForThrowable(jnienv);
        jplis_assert(!errorOccurred);
    }

    if (!errorOccurred) {
        classDefs = (jvmtiClassDefinition *) allocate(
                                                jvmtienv,
                                                numDefs * sizeof(jvmtiClassDefinition));
        errorOccurred = (classDefs == NULL);
        jplis_assert(!errorOccurred);
        if ( errorOccurred ) {
            createAndThrowThrowableFromJVMTIErrorCode(jnienv, JVMTI_ERROR_OUT_OF_MEMORY);
        }

        else {
            /*
             * We have to save the targetFile values that we compute so
             * that we can release the class_bytes arrays that are
             * returned by GetByteArrayElements(). In case of a JNI
             * error, we can't (easily) recompute the targetFile values
             * and we still want to free any memory we allocated.
             */
            targetFiles = (jbyteArray *) allocate(jvmtienv,
                                                  numDefs * sizeof(jbyteArray));
            errorOccurred = (targetFiles == NULL);
            jplis_assert(!errorOccurred);
            if ( errorOccurred ) {
                deallocate(jvmtienv, (void*)classDefs);
                createAndThrowThrowableFromJVMTIErrorCode(jnienv,
                    JVMTI_ERROR_OUT_OF_MEMORY);
            }
            else {
                jint i, j;

                // clear classDefs so we can correctly free memory during errors
                memset(classDefs, 0, numDefs * sizeof(jvmtiClassDefinition));

                for (i = 0; i < numDefs; i++) {
                    jclass      classDef    = NULL;

                    classDef = (*jnienv)->GetObjectArrayElement(jnienv, classDefinitions, i);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (errorOccurred) {
                        break;
                    }

                    classDefs[i].klass = (*jnienv)->CallObjectMethod(jnienv, classDef, getDefinitionClassMethodID);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (errorOccurred) {
                        break;
                    }

                    targetFiles[i] = (*jnienv)->CallObjectMethod(jnienv, classDef, getDefinitionClassFileMethodID);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (errorOccurred) {
                        break;
                    }

                    classDefs[i].class_byte_count = (*jnienv)->GetArrayLength(jnienv, targetFiles[i]);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (errorOccurred) {
                        break;
                    }

                    /*
                     * Allocate class_bytes last so we don't have to free
                     * memory on a partial row error.
                     */
                    classDefs[i].class_bytes = (unsigned char*)(*jnienv)->GetByteArrayElements(jnienv, targetFiles[i], NULL);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (errorOccurred) {
                        break;
                    }
                }

                if (!errorOccurred) {
                    jvmtiError  errorCode = JVMTI_ERROR_NONE;
                    errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
                    if (errorCode == JVMTI_ERROR_WRONG_PHASE) {
                        /* insulate caller from the wrong phase error */
                        errorCode = JVMTI_ERROR_NONE;
                    } else {
                        errorOccurred = (errorCode != JVMTI_ERROR_NONE);
                        if ( errorOccurred ) {
                            createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
                        }
                    }
                }

                /*
                 * Cleanup memory that we allocated above. If we had a
                 * JNI error, a JVM/TI error or no errors, index 'i'
                 * tracks how far we got in processing the classDefs
                 * array. Note:  ReleaseByteArrayElements() is safe to
                 * call with a JNI exception pending.
                 */
                for (j = 0; j < i; j++) {
                    if ((jbyte *)classDefs[j].class_bytes != NULL) {
                        (*jnienv)->ReleaseByteArrayElements(jnienv,
                            targetFiles[j], (jbyte *)classDefs[j].class_bytes,
                            0 /* copy back and free */);
                        /*
                         * Only check for error if we didn't already have one
                         * so we don't overwrite errorOccurred.
                         */
                        if (!errorOccurred) {
                            errorOccurred = checkForThrowable(jnienv);
                            jplis_assert(!errorOccurred);
                        }
                    }
                }
                deallocate(jvmtienv, (void*)targetFiles);
                deallocate(jvmtienv, (void*)classDefs);
            }
        }
    }

    mapThrownThrowableIfNecessary(jnienv, redefineClassMapper);
}

/* Cheesy sharing. ClassLoader may be null. */
jobjectArray
commonGetClassList( JNIEnv *            jnienv,
                    JPLISAgent *        agent,
                    jobject             classLoader,
                    ClassListFetcher    fetcher) {
    jvmtiEnv *      jvmtienv        = jvmti(agent);
    jboolean        errorOccurred   = JNI_FALSE;
    jvmtiError      jvmtierror      = JVMTI_ERROR_NONE;
    jint            classCount      = 0;
    jclass *        classes         = NULL;
    jobjectArray    localArray      = NULL;

    /* retrieve the classes from the JVMTI agent */
    jvmtierror = (*fetcher)( jvmtienv,
                        classLoader,
                        &classCount,
                        &classes);
    check_phase_ret_blob(jvmtierror, localArray);
    errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
    jplis_assert(!errorOccurred);

    if ( errorOccurred ) {
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
    } else {
        localArray = getObjectArrayFromClasses( jnienv,
                                                classes,
                                                classCount);
        errorOccurred = checkForThrowable(jnienv);
        jplis_assert(!errorOccurred);

        /* do this whether or not we saw a problem */
        deallocate(jvmtienv, (void*)classes);
    }

    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
    return localArray;

}

jvmtiError
getAllLoadedClassesClassListFetcher(    jvmtiEnv *  jvmtienv,
                                        jobject     classLoader,
                                        jint *      classCount,
                                        jclass **   classes) {
    return (*jvmtienv)->GetLoadedClasses(jvmtienv, classCount, classes);
}

jobjectArray
getAllLoadedClasses(JNIEnv * jnienv, JPLISAgent * agent) {
    return commonGetClassList(  jnienv,
                                agent,
                                NULL,
                                getAllLoadedClassesClassListFetcher);
}

jvmtiError
getInitiatedClassesClassListFetcher(    jvmtiEnv *  jvmtienv,
                                        jobject     classLoader,
                                        jint *      classCount,
                                        jclass **   classes) {
    return (*jvmtienv)->GetClassLoaderClasses(jvmtienv, classLoader, classCount, classes);
}


jobjectArray
getInitiatedClasses(JNIEnv * jnienv, JPLISAgent * agent, jobject classLoader) {
    return commonGetClassList(  jnienv,
                                agent,
                                classLoader,
                                getInitiatedClassesClassListFetcher);
}

jlong
getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize) {
    jvmtiEnv *  jvmtienv    = jvmti(agent);
    jlong       objectSize  = -1;
    jvmtiError  jvmtierror  = JVMTI_ERROR_NONE;

    jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
    check_phase_ret_0(jvmtierror);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    if ( jvmtierror != JVMTI_ERROR_NONE ) {
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
    }

    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
    return objectSize;
}

void
appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile, jboolean isBootLoader)
{
    jvmtiEnv *  jvmtienv    = jvmti(agent);
    jboolean    errorOutstanding;
    jvmtiError  jvmtierror;
    const char* utf8Chars;
    jsize       utf8Len;
    jboolean    isCopy;
    char        platformChars[MAXPATHLEN];
    int         platformLen;

    utf8Len = (*jnienv)->GetStringUTFLength(jnienv, jarFile);
    errorOutstanding = checkForAndClearThrowable(jnienv);

    if (!errorOutstanding) {
        utf8Chars = (*jnienv)->GetStringUTFChars(jnienv, jarFile, &isCopy);
        errorOutstanding = checkForAndClearThrowable(jnienv);

        if (!errorOutstanding && utf8Chars != NULL) {
            /*
             * JVMTI spec'ed to use modified UTF8. At this time this is not implemented
             * the platform encoding is used.
             */
            platformLen = convertUft8ToPlatformString((char*)utf8Chars, utf8Len, platformChars, MAXPATHLEN);
            if (platformLen < 0) {
                createAndThrowInternalError(jnienv);
                return;
            }

            (*jnienv)->ReleaseStringUTFChars(jnienv, jarFile, utf8Chars);
            errorOutstanding = checkForAndClearThrowable(jnienv);

            if (!errorOutstanding) {

                if (isBootLoader) {
                    jvmtierror = (*jvmtienv)->AddToBootstrapClassLoaderSearch(jvmtienv, platformChars);
                } else {
                    jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
                }
                check_phase_ret(jvmtierror);

                if ( jvmtierror != JVMTI_ERROR_NONE ) {
                    createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
                }
            }
        }
    }

    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
}

/*
 *  Set the prefixes used to wrap native methods (so they can be instrumented).
 *  Each transform can set a prefix, any that have been set come in as prefixArray.
 *  Convert them in native strings in a native array then call JVM TI.
 *  One a given call, this function handles either the prefixes for retransformable
 *  transforms or for normal transforms.
 */
void
setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefixArray,
                        jboolean isRetransformable) {
    jvmtiEnv*   jvmtienv;
    jvmtiError  err                             = JVMTI_ERROR_NONE;
    jsize       arraySize;
    jboolean    errorOccurred                   = JNI_FALSE;

    jplis_assert(prefixArray != NULL);

    if (isRetransformable) {
        jvmtienv = agent->mRetransformEnvironment.mJVMTIEnv;
    } else {
        jvmtienv = agent->mNormalEnvironment.mJVMTIEnv;
    }
    arraySize = (*jnienv)->GetArrayLength(jnienv, prefixArray);
    errorOccurred = checkForThrowable(jnienv);
    jplis_assert(!errorOccurred);

    if (!errorOccurred) {
        /* allocate the native to hold the native prefixes */
        const char** prefixes = (const char**) allocate(jvmtienv,
                                                        arraySize * sizeof(char*));
        /* since JNI ReleaseStringUTFChars needs the jstring from which the native
         * string was allocated, we store them in a parallel array */
        jstring* originForRelease = (jstring*) allocate(jvmtienv,
                                                        arraySize * sizeof(jstring));
        errorOccurred = (prefixes == NULL || originForRelease == NULL);
        jplis_assert(!errorOccurred);
        if ( errorOccurred ) {
            createAndThrowThrowableFromJVMTIErrorCode(jnienv, JVMTI_ERROR_OUT_OF_MEMORY);
        }
        else {
            jint inx = 0;
            jint i;
            for (i = 0; i < arraySize; i++) {
                jstring      prefixStr  = NULL;
                const char*  prefix;
                jsize        prefixLen;
                jboolean     isCopy;

                prefixStr = (jstring) ((*jnienv)->GetObjectArrayElement(jnienv,
                                                                        prefixArray, i));
                errorOccurred = checkForThrowable(jnienv);
                jplis_assert(!errorOccurred);
                if (errorOccurred) {
                    break;
                }
                if (prefixStr == NULL) {
                    continue;
                }

                prefixLen = (*jnienv)->GetStringUTFLength(jnienv, prefixStr);
                errorOccurred = checkForThrowable(jnienv);
                jplis_assert(!errorOccurred);
                if (errorOccurred) {
                    break;
                }

                if (prefixLen > 0) {
                    prefix = (*jnienv)->GetStringUTFChars(jnienv, prefixStr, &isCopy);
                    errorOccurred = checkForThrowable(jnienv);
                    jplis_assert(!errorOccurred);
                    if (!errorOccurred && prefix != NULL) {
                        prefixes[inx] = prefix;
                        originForRelease[inx] = prefixStr;
                        ++inx;
                    }
                }
            }

            err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
            /* can be called from any phase */
            jplis_assert(err == JVMTI_ERROR_NONE);

            for (i = 0; i < inx; i++) {
              (*jnienv)->ReleaseStringUTFChars(jnienv, originForRelease[i], prefixes[i]);
            }
        }
        deallocate(jvmtienv, (void*)prefixes);
        deallocate(jvmtienv, (void*)originForRelease);
    }
}
