/*
 * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include <ctype.h>

#include "util.h"
#include "transport.h"
#include "eventHandler.h"
#include "threadControl.h"
#include "outStream.h"
#include "inStream.h"
#include "invoker.h"

/* Global data area */
BackendGlobalData *gdata = NULL;

/* Forward declarations */
static jboolean isInterface(jclass clazz);
static jboolean isArrayClass(jclass clazz);
static char * getPropertyUTF8(JNIEnv *env, char *propertyName);

/* Save an object reference for use later (create a NewGlobalRef) */
void
saveGlobalRef(JNIEnv *env, jobject obj, jobject *pobj)
{
    jobject newobj;

    if ( pobj == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef pobj");
    }
    if ( *pobj != NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef *pobj");
    }
    if ( env == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef env");
    }
    if ( obj == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"saveGlobalRef obj");
    }
    newobj = JNI_FUNC_PTR(env,NewGlobalRef)(env, obj);
    if ( newobj == NULL ) {
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewGlobalRef");
    }
    *pobj = newobj;
}

/* Toss a previously saved object reference */
void
tossGlobalRef(JNIEnv *env, jobject *pobj)
{
    jobject obj;

    if ( pobj == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef pobj");
    }
    obj = *pobj;
    if ( env == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"tossGlobalRef env");
    }
    if ( obj == NULL ) {
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"tossGlobalRef obj");
    }
    JNI_FUNC_PTR(env,DeleteGlobalRef)(env, obj);
    *pobj = NULL;
}

static jclass
findClass(JNIEnv *env, const char * name)
{
    jclass x;

    if ( env == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass env");
    }
    if ( name == NULL || name[0] == 0 ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"findClass name");
    }
    x = JNI_FUNC_PTR(env,FindClass)(env, name);
    if (x == NULL) {
        ERROR_MESSAGE(("JDWP Can't find class %s", name));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
        ERROR_MESSAGE(("JDWP Exception occurred finding class %s", name));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    return x;
}

static jmethodID
getMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
{
    jmethodID method;

    if ( env == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod env");
    }
    if ( clazz == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod clazz");
    }
    if ( name == NULL || name[0] == 0 ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod name");
    }
    if ( signature == NULL || signature[0] == 0 ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getMethod signature");
    }
    method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, signature);
    if (method == NULL) {
        ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
                                name, signature));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
        ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
                                name, signature));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    return method;
}

static jmethodID
getStaticMethod(JNIEnv *env, jclass clazz, const char * name, const char *signature)
{
    jmethodID method;

    if ( env == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod env");
    }
    if ( clazz == NULL ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod clazz");
    }
    if ( name == NULL || name[0] == 0 ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod name");
    }
    if ( signature == NULL || signature[0] == 0 ) {
        EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"getStaticMethod signature");
    }
    method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, signature);
    if (method == NULL) {
        ERROR_MESSAGE(("JDWP Can't find method %s with signature %s",
                                name, signature));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    if ( JNI_FUNC_PTR(env,ExceptionOccurred)(env) ) {
        ERROR_MESSAGE(("JDWP Exception occurred finding method %s with signature %s",
                                name, signature));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    return method;
}

void
util_initialize(JNIEnv *env)
{
    WITH_LOCAL_REFS(env, 6) {

        jvmtiError error;
        jclass localClassClass;
        jclass localThreadClass;
        jclass localThreadGroupClass;
        jclass localClassLoaderClass;
        jclass localStringClass;
        jclass localSystemClass;
        jclass localPropertiesClass;
        jclass localVMSupportClass;
        jobject localAgentProperties;
        jmethodID getAgentProperties;
        jint groupCount;
        jthreadGroup *groups;
        jthreadGroup localSystemThreadGroup;

        /* Find some standard classes */

        localClassClass         = findClass(env,"java/lang/Class");
        localThreadClass        = findClass(env,"java/lang/Thread");
        localThreadGroupClass   = findClass(env,"java/lang/ThreadGroup");
        localClassLoaderClass   = findClass(env,"java/lang/ClassLoader");
        localStringClass        = findClass(env,"java/lang/String");
        localSystemClass        = findClass(env,"java/lang/System");
        localPropertiesClass    = findClass(env,"java/util/Properties");

        /* Save references */

        saveGlobalRef(env, localClassClass,       &(gdata->classClass));
        saveGlobalRef(env, localThreadClass,      &(gdata->threadClass));
        saveGlobalRef(env, localThreadGroupClass, &(gdata->threadGroupClass));
        saveGlobalRef(env, localClassLoaderClass, &(gdata->classLoaderClass));
        saveGlobalRef(env, localStringClass,      &(gdata->stringClass));
        saveGlobalRef(env, localSystemClass,      &(gdata->systemClass));

        /* Find some standard methods */

        gdata->threadConstructor =
                getMethod(env, gdata->threadClass,
                    "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
        gdata->threadSetDaemon =
                getMethod(env, gdata->threadClass, "setDaemon", "(Z)V");
        gdata->threadResume =
                getMethod(env, gdata->threadClass, "resume", "()V");
        gdata->systemGetProperty =
                getStaticMethod(env, gdata->systemClass,
                    "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
        gdata->setProperty =
                getMethod(env, localPropertiesClass,
                    "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");

        /* Find the system thread group */

        groups = NULL;
        groupCount = 0;
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
                    (gdata->jvmti, &groupCount, &groups);
        if (error != JVMTI_ERROR_NONE ) {
            EXIT_ERROR(error, "Can't get system thread group");
        }
        if ( groupCount == 0 ) {
            EXIT_ERROR(AGENT_ERROR_NULL_POINTER, "Can't get system thread group");
        }
        localSystemThreadGroup = groups[0];
        saveGlobalRef(env, localSystemThreadGroup, &(gdata->systemThreadGroup));

        /* Get some basic Java property values we will need at some point */
        gdata->property_java_version
                        = getPropertyUTF8(env, "java.version");
        gdata->property_java_vm_name
                        = getPropertyUTF8(env, "java.vm.name");
        gdata->property_java_vm_info
                        = getPropertyUTF8(env, "java.vm.info");
        gdata->property_java_class_path
                        = getPropertyUTF8(env, "java.class.path");
        gdata->property_sun_boot_class_path
                        = getPropertyUTF8(env, "sun.boot.class.path");
        gdata->property_sun_boot_library_path
                        = getPropertyUTF8(env, "sun.boot.library.path");
        gdata->property_path_separator
                        = getPropertyUTF8(env, "path.separator");
        gdata->property_user_dir
                        = getPropertyUTF8(env, "user.dir");

        /* Get agent properties: invoke sun.misc.VMSupport.getAgentProperties */
        localVMSupportClass = JNI_FUNC_PTR(env,FindClass)
                                          (env, "sun/misc/VMSupport");
        if (localVMSupportClass == NULL) {
            gdata->agent_properties = NULL;
            if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
                JNI_FUNC_PTR(env,ExceptionClear)(env);
            }
        } else {
            getAgentProperties  =
                getStaticMethod(env, localVMSupportClass,
                                "getAgentProperties", "()Ljava/util/Properties;");
            localAgentProperties =
                JNI_FUNC_PTR(env,CallStaticObjectMethod)
                            (env, localVMSupportClass, getAgentProperties);
            saveGlobalRef(env, localAgentProperties, &(gdata->agent_properties));
            if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
                JNI_FUNC_PTR(env,ExceptionClear)(env);
                EXIT_ERROR(AGENT_ERROR_INTERNAL,
                    "Exception occurred calling sun.misc.VMSupport.getAgentProperties");
            }
        }

    } END_WITH_LOCAL_REFS(env);

}

void
util_reset(void)
{
}

jboolean
isObjectTag(jbyte tag) {
    return (tag == JDWP_TAG(OBJECT)) ||
           (tag == JDWP_TAG(STRING)) ||
           (tag == JDWP_TAG(THREAD)) ||
           (tag == JDWP_TAG(THREAD_GROUP)) ||
           (tag == JDWP_TAG(CLASS_LOADER)) ||
           (tag == JDWP_TAG(CLASS_OBJECT)) ||
           (tag == JDWP_TAG(ARRAY));
}

jbyte
specificTypeKey(JNIEnv *env, jobject object)
{
    if (object == NULL) {
        return JDWP_TAG(OBJECT);
    } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass)) {
        return JDWP_TAG(STRING);
    } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass)) {
        return JDWP_TAG(THREAD);
    } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass)) {
        return JDWP_TAG(THREAD_GROUP);
    } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass)) {
        return JDWP_TAG(CLASS_LOADER);
    } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass)) {
        return JDWP_TAG(CLASS_OBJECT);
    } else {
        jboolean classIsArray;

        WITH_LOCAL_REFS(env, 1) {
            jclass clazz;
            clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
            classIsArray = isArrayClass(clazz);
        } END_WITH_LOCAL_REFS(env);

        return (classIsArray ? JDWP_TAG(ARRAY) : JDWP_TAG(OBJECT));
    }
}

static void
writeFieldValue(JNIEnv *env, PacketOutputStream *out, jobject object,
                jfieldID field)
{
    jclass clazz;
    char *signature = NULL;
    jvmtiError error;
    jbyte typeKey;

    clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
    error = fieldSignature(clazz, field, NULL, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }
    typeKey = signature[0];
    jvmtiDeallocate(signature);

    /*
     * For primitive types, the type key is bounced back as is. Objects
     * are handled in the switch statement below.
     */
    if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
        (void)outStream_writeByte(out, typeKey);
    }

    switch (typeKey) {
        case JDWP_TAG(OBJECT):
        case JDWP_TAG(ARRAY):   {
            jobject value = JNI_FUNC_PTR(env,GetObjectField)(env, object, field);
            (void)outStream_writeByte(out, specificTypeKey(env, value));
            (void)outStream_writeObjectRef(env, out, value);
            break;
        }

        case JDWP_TAG(BYTE):
            (void)outStream_writeByte(out,
                      JNI_FUNC_PTR(env,GetByteField)(env, object, field));
            break;

        case JDWP_TAG(CHAR):
            (void)outStream_writeChar(out,
                      JNI_FUNC_PTR(env,GetCharField)(env, object, field));
            break;

        case JDWP_TAG(FLOAT):
            (void)outStream_writeFloat(out,
                      JNI_FUNC_PTR(env,GetFloatField)(env, object, field));
            break;

        case JDWP_TAG(DOUBLE):
            (void)outStream_writeDouble(out,
                      JNI_FUNC_PTR(env,GetDoubleField)(env, object, field));
            break;

        case JDWP_TAG(INT):
            (void)outStream_writeInt(out,
                      JNI_FUNC_PTR(env,GetIntField)(env, object, field));
            break;

        case JDWP_TAG(LONG):
            (void)outStream_writeLong(out,
                      JNI_FUNC_PTR(env,GetLongField)(env, object, field));
            break;

        case JDWP_TAG(SHORT):
            (void)outStream_writeShort(out,
                      JNI_FUNC_PTR(env,GetShortField)(env, object, field));
            break;

        case JDWP_TAG(BOOLEAN):
            (void)outStream_writeBoolean(out,
                      JNI_FUNC_PTR(env,GetBooleanField)(env, object, field));
            break;
    }
}

static void
writeStaticFieldValue(JNIEnv *env, PacketOutputStream *out, jclass clazz,
                      jfieldID field)
{
    jvmtiError error;
    char *signature = NULL;
    jbyte typeKey;

    error = fieldSignature(clazz, field, NULL, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return;
    }
    typeKey = signature[0];
    jvmtiDeallocate(signature);

    /*
     * For primitive types, the type key is bounced back as is. Objects
     * are handled in the switch statement below.
     */
    if ((typeKey != JDWP_TAG(OBJECT)) && (typeKey != JDWP_TAG(ARRAY))) {
        (void)outStream_writeByte(out, typeKey);
    }

    switch (typeKey) {
        case JDWP_TAG(OBJECT):
        case JDWP_TAG(ARRAY):   {
            jobject value = JNI_FUNC_PTR(env,GetStaticObjectField)(env, clazz, field);
            (void)outStream_writeByte(out, specificTypeKey(env, value));
            (void)outStream_writeObjectRef(env, out, value);
            break;
        }

        case JDWP_TAG(BYTE):
            (void)outStream_writeByte(out,
                      JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field));
            break;

        case JDWP_TAG(CHAR):
            (void)outStream_writeChar(out,
                      JNI_FUNC_PTR(env,GetStaticCharField)(env, clazz, field));
            break;

        case JDWP_TAG(FLOAT):
            (void)outStream_writeFloat(out,
                      JNI_FUNC_PTR(env,GetStaticFloatField)(env, clazz, field));
            break;

        case JDWP_TAG(DOUBLE):
            (void)outStream_writeDouble(out,
                      JNI_FUNC_PTR(env,GetStaticDoubleField)(env, clazz, field));
            break;

        case JDWP_TAG(INT):
            (void)outStream_writeInt(out,
                      JNI_FUNC_PTR(env,GetStaticIntField)(env, clazz, field));
            break;

        case JDWP_TAG(LONG):
            (void)outStream_writeLong(out,
                      JNI_FUNC_PTR(env,GetStaticLongField)(env, clazz, field));
            break;

        case JDWP_TAG(SHORT):
            (void)outStream_writeShort(out,
                      JNI_FUNC_PTR(env,GetStaticShortField)(env, clazz, field));
            break;

        case JDWP_TAG(BOOLEAN):
            (void)outStream_writeBoolean(out,
                      JNI_FUNC_PTR(env,GetStaticBooleanField)(env, clazz, field));
            break;
    }
}

void
sharedGetFieldValues(PacketInputStream *in, PacketOutputStream *out,
                     jboolean isStatic)
{
    JNIEnv *env = getEnv();
    jint length;
    jobject object;
    jclass clazz;

    object = NULL;
    clazz  = NULL;

    if (isStatic) {
        clazz = inStream_readClassRef(env, in);
    } else {
        object = inStream_readObjectRef(env, in);
    }

    length = inStream_readInt(in);
    if (inStream_error(in)) {
        return;
    }

    WITH_LOCAL_REFS(env, length + 1) { /* +1 for class with instance fields */

        int i;

        (void)outStream_writeInt(out, length);
        for (i = 0; (i < length) && !outStream_error(out); i++) {
            jfieldID field = inStream_readFieldID(in);

            if (isStatic) {
                writeStaticFieldValue(env, out, clazz, field);
            } else {
                writeFieldValue(env, out, object, field);
            }
        }

    } END_WITH_LOCAL_REFS(env);
}

jboolean
sharedInvoke(PacketInputStream *in, PacketOutputStream *out)
{
    jvalue *arguments = NULL;
    jint options;
    jvmtiError error;
    jbyte invokeType;
    jclass clazz;
    jmethodID method;
    jint argumentCount;
    jobject instance;
    jthread thread;
    JNIEnv *env;

    /*
     * Instance methods start with the instance, thread and class,
     * and statics and constructors start with the class and then the
     * thread.
     */
    env = getEnv();
    if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
        instance = inStream_readObjectRef(env, in);
        thread = inStream_readThreadRef(env, in);
        clazz = inStream_readClassRef(env, in);
    } else { /* static method or constructor */
        instance = NULL;
        clazz = inStream_readClassRef(env, in);
        thread = inStream_readThreadRef(env, in);
    }

    /*
     * ... and the rest of the packet is identical for all commands
     */
    method = inStream_readMethodID(in);
    argumentCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    /* If count == 0, don't try and allocate 0 bytes, you'll get NULL */
    if ( argumentCount > 0 ) {
        int i;
        /*LINTED*/
        arguments = jvmtiAllocate(argumentCount * (jint)sizeof(*arguments));
        if (arguments == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
            return JNI_TRUE;
        }
        for (i = 0; (i < argumentCount) && !inStream_error(in); i++) {
            arguments[i] = inStream_readValue(in, NULL);
        }
        if (inStream_error(in)) {
            return JNI_TRUE;
        }
    }

    options = inStream_readInt(in);
    if (inStream_error(in)) {
        if ( arguments != NULL ) {
            jvmtiDeallocate(arguments);
        }
        return JNI_TRUE;
    }

    if (inStream_command(in) == JDWP_COMMAND(ClassType, NewInstance)) {
        invokeType = INVOKE_CONSTRUCTOR;
    } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) {
        invokeType = INVOKE_STATIC;
    } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
        invokeType = INVOKE_INSTANCE;
    } else {
        outStream_setError(out, JDWP_ERROR(INTERNAL));
        if ( arguments != NULL ) {
            jvmtiDeallocate(arguments);
        }
        return JNI_TRUE;
    }

    /*
     * Request the invoke. If there are no errors in the request,
     * the interrupting thread will actually do the invoke and a
     * reply will be generated subsequently, so we don't reply here.
     */
    error = invoker_requestInvoke(invokeType, (jbyte)options, inStream_id(in),
                                  thread, clazz, method,
                                  instance, arguments, argumentCount);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        if ( arguments != NULL ) {
            jvmtiDeallocate(arguments);
        }
        return JNI_TRUE;
    }

    return JNI_FALSE;   /* Don't reply */
}

jint
uniqueID(void)
{
    static jint currentID = 0;
    return currentID++;
}

int
filterDebugThreads(jthread *threads, int count)
{
    int i;
    int current;

    /* Squish out all of the debugger-spawned threads */
    for (i = 0, current = 0; i < count; i++) {
        jthread thread = threads[i];
        if (!threadControl_isDebugThread(thread)) {
            if (i > current) {
                threads[current] = thread;
            }
            current++;
        }
    }
    return current;
}

jbyte
referenceTypeTag(jclass clazz)
{
    jbyte tag;

    if (isInterface(clazz)) {
        tag = JDWP_TYPE_TAG(INTERFACE);
    } else if (isArrayClass(clazz)) {
        tag = JDWP_TYPE_TAG(ARRAY);
    } else {
        tag = JDWP_TYPE_TAG(CLASS);
    }

    return tag;
}

/**
 * Get field modifiers
 */
jvmtiError
fieldModifiers(jclass clazz, jfieldID field, jint *pmodifiers)
{
    jvmtiError error;

    *pmodifiers = 0;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
            (gdata->jvmti, clazz, field, pmodifiers);
    return error;
}

/**
 * Get method modifiers
 */
jvmtiError
methodModifiers(jmethodID method, jint *pmodifiers)
{
    jvmtiError error;

    *pmodifiers = 0;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodModifiers)
            (gdata->jvmti, method, pmodifiers);
    return error;
}

/* Returns a local ref to the declaring class for a method, or NULL. */
jvmtiError
methodClass(jmethodID method, jclass *pclazz)
{
    jvmtiError error;

    *pclazz = NULL;
    error = FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
                                (gdata->jvmti, method, pclazz);
    return error;
}

/* Returns a local ref to the declaring class for a method, or NULL. */
jvmtiError
methodLocation(jmethodID method, jlocation *ploc1, jlocation *ploc2)
{
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodLocation)
                                (gdata->jvmti, method, ploc1, ploc2);
    return error;
}

/**
 * Get method signature
 */
jvmtiError
methodSignature(jmethodID method,
        char **pname, char **psignature, char **pgeneric_signature)
{
    jvmtiError error;
    char *name = NULL;
    char *signature = NULL;
    char *generic_signature = NULL;

    error = FUNC_PTR(gdata->jvmti,GetMethodName)
            (gdata->jvmti, method, &name, &signature, &generic_signature);

    if ( pname != NULL ) {
        *pname = name;
    } else if ( name != NULL )  {
        jvmtiDeallocate(name);
    }
    if ( psignature != NULL ) {
        *psignature = signature;
    } else if ( signature != NULL ) {
        jvmtiDeallocate(signature);
    }
    if ( pgeneric_signature != NULL ) {
        *pgeneric_signature = generic_signature;
    } else if ( generic_signature != NULL )  {
        jvmtiDeallocate(generic_signature);
    }
    return error;
}

/*
 * Get the return type key of the method
 *     V or B C D F I J S Z L  [
 */
jvmtiError
methodReturnType(jmethodID method, char *typeKey)
{
    char       *signature;
    jvmtiError  error;

    signature = NULL;
    error     = methodSignature(method, NULL, &signature, NULL);
    if (error == JVMTI_ERROR_NONE) {
        if (signature == NULL ) {
            error = AGENT_ERROR_INVALID_TAG;
        } else {
            char * xx;

            xx = strchr(signature, ')');
            if (xx == NULL || *(xx + 1) == 0) {
                error = AGENT_ERROR_INVALID_TAG;
            } else {
               *typeKey = *(xx + 1);
            }
            jvmtiDeallocate(signature);
        }
    }
    return error;
}


/**
 * Return class loader for a class (must be inside a WITH_LOCAL_REFS)
 */
jvmtiError
classLoader(jclass clazz, jobject *pclazz)
{
    jvmtiError error;

    *pclazz = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
            (gdata->jvmti, clazz, pclazz);
    return error;
}

/**
 * Get field signature
 */
jvmtiError
fieldSignature(jclass clazz, jfieldID field,
        char **pname, char **psignature, char **pgeneric_signature)
{
    jvmtiError error;
    char *name = NULL;
    char *signature = NULL;
    char *generic_signature = NULL;

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
            (gdata->jvmti, clazz, field, &name, &signature, &generic_signature);

    if ( pname != NULL ) {
        *pname = name;
    } else if ( name != NULL )  {
        jvmtiDeallocate(name);
    }
    if ( psignature != NULL ) {
        *psignature = signature;
    } else if ( signature != NULL )  {
        jvmtiDeallocate(signature);
    }
    if ( pgeneric_signature != NULL ) {
        *pgeneric_signature = generic_signature;
    } else if ( generic_signature != NULL )  {
        jvmtiDeallocate(generic_signature);
    }
    return error;
}

JNIEnv *
getEnv(void)
{
    JNIEnv *env = NULL;
    jint rc;

    rc = FUNC_PTR(gdata->jvm,GetEnv)
                (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
    if (rc != JNI_OK) {
        ERROR_MESSAGE(("JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = %d",
                rc));
        EXIT_ERROR(AGENT_ERROR_NO_JNI_ENV,NULL);
    }
    return env;
}

jvmtiError
spawnNewThread(jvmtiStartFunction func, void *arg, char *name)
{
    JNIEnv *env = getEnv();
    jvmtiError error;

    LOG_MISC(("Spawning new thread: %s", name));

    WITH_LOCAL_REFS(env, 3) {

        jthread thread;
        jstring nameString;

        nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            JNI_FUNC_PTR(env,ExceptionClear)(env);
            error = AGENT_ERROR_OUT_OF_MEMORY;
            goto err;
        }

        thread = JNI_FUNC_PTR(env,NewObject)
                        (env, gdata->threadClass, gdata->threadConstructor,
                                   gdata->systemThreadGroup, nameString);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            JNI_FUNC_PTR(env,ExceptionClear)(env);
            error = AGENT_ERROR_OUT_OF_MEMORY;
            goto err;
        }

        /*
         * Make the debugger thread a daemon
         */
        JNI_FUNC_PTR(env,CallVoidMethod)
                        (env, thread, gdata->threadSetDaemon, JNI_TRUE);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            JNI_FUNC_PTR(env,ExceptionClear)(env);
            error = AGENT_ERROR_JNI_EXCEPTION;
            goto err;
        }

        error = threadControl_addDebugThread(thread);
        if (error == JVMTI_ERROR_NONE) {
            /*
             * Debugger threads need cycles in all sorts of strange
             * situations (e.g. infinite cpu-bound loops), so give the
             * thread a high priority. Note that if the VM has an application
             * thread running at the max priority, there is still a chance
             * that debugger threads will be starved. (There needs to be
             * a way to give debugger threads a priority higher than any
             * application thread).
             */
            error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
                        (gdata->jvmti, thread, func, arg,
                                        JVMTI_THREAD_MAX_PRIORITY);
        }

        err: ;

    } END_WITH_LOCAL_REFS(env);

    return error;
}

jvmtiError
jvmtiGetCapabilities(jvmtiCapabilities *caps)
{
    if ( gdata->vmDead ) {
        return AGENT_ERROR_VM_DEAD;
    }
    if (!gdata->haveCachedJvmtiCapabilities) {
        jvmtiError error;

        error = JVMTI_FUNC_PTR(gdata->jvmti,GetCapabilities)
                        (gdata->jvmti, &(gdata->cachedJvmtiCapabilities));
        if (error != JVMTI_ERROR_NONE) {
            return error;
        }
        gdata->haveCachedJvmtiCapabilities = JNI_TRUE;
    }

    *caps = gdata->cachedJvmtiCapabilities;

    return JVMTI_ERROR_NONE;
}

static jint
jvmtiVersion(void)
{
    if (gdata->cachedJvmtiVersion == 0) {
        jvmtiError error;
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
                        (gdata->jvmti, &(gdata->cachedJvmtiVersion));
        if (error != JVMTI_ERROR_NONE) {
            EXIT_ERROR(error, "on getting the JVMTI version number");
        }
    }
    return gdata->cachedJvmtiVersion;
}

jint
jvmtiMajorVersion(void)
{
    return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
                    >> JVMTI_VERSION_SHIFT_MAJOR;
}

jint
jvmtiMinorVersion(void)
{
    return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
                    >> JVMTI_VERSION_SHIFT_MINOR;
}

jint
jvmtiMicroVersion(void)
{
    return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
                    >> JVMTI_VERSION_SHIFT_MICRO;
}

jboolean
canSuspendResumeThreadLists(void)
{
    jvmtiError error;
    jvmtiCapabilities cap;

    error = jvmtiGetCapabilities(&cap);
    return (error == JVMTI_ERROR_NONE && cap.can_suspend);
}

jvmtiError
getSourceDebugExtension(jclass clazz, char **extensionPtr)
{
    return JVMTI_FUNC_PTR(gdata->jvmti,GetSourceDebugExtension)
                (gdata->jvmti, clazz, extensionPtr);
}

/*
 * Convert the signature "Ljava/lang/Foo;" to a
 * classname "java.lang.Foo" compatible with the pattern.
 * Signature is overwritten in-place.
 */
void
convertSignatureToClassname(char *convert)
{
    char *p;

    p = convert + 1;
    while ((*p != ';') && (*p != '\0')) {
        char c = *p;
        if (c == '/') {
            *(p-1) = '.';
        } else {
            *(p-1) = c;
        }
        p++;
    }
    *(p-1) = '\0';
}

static void
handleInterrupt(void)
{
    /*
     * An interrupt is handled:
     *
     * 1) for running application threads by deferring the interrupt
     * until the current event handler has concluded.
     *
     * 2) for debugger threads by ignoring the interrupt; this is the
     * most robust solution since debugger threads don't use interrupts
     * to signal any condition.
     *
     * 3) for application threads that have not started or already
     * ended by ignoring the interrupt. In the former case, the application
     * is relying on timing to determine whether or not the thread sees
     * the interrupt; in the latter case, the interrupt is meaningless.
     */
    jthread thread = threadControl_currentThread();
    if ((thread != NULL) && (!threadControl_isDebugThread(thread))) {
        threadControl_setPendingInterrupt(thread);
    }
}

static jvmtiError
ignore_vm_death(jvmtiError error)
{
    if (error == JVMTI_ERROR_WRONG_PHASE) {
        LOG_MISC(("VM_DEAD, in debugMonitor*()?"));
        return JVMTI_ERROR_NONE; /* JVMTI does this, not JVMDI? */
    }
    return error;
}

void
debugMonitorEnter(jrawMonitorID monitor)
{
    jvmtiError error;
    while (JNI_TRUE) {
        error = FUNC_PTR(gdata->jvmti,RawMonitorEnter)
                        (gdata->jvmti, monitor);
        error = ignore_vm_death(error);
        if (error == JVMTI_ERROR_INTERRUPT) {
            handleInterrupt();
        } else {
            break;
        }
    }
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor enter");
    }
}

void
debugMonitorExit(jrawMonitorID monitor)
{
    jvmtiError error;

    error = FUNC_PTR(gdata->jvmti,RawMonitorExit)
                (gdata->jvmti, monitor);
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor exit");
    }
}

void
debugMonitorWait(jrawMonitorID monitor)
{
    jvmtiError error;
    error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
        (gdata->jvmti, monitor, ((jlong)(-1)));

    /*
     * According to the JLS (17.8), here we have
     * either :
     * a- been notified
     * b- gotten a suprious wakeup
     * c- been interrupted
     * If both a and c have happened, the VM must choose
     * which way to return - a or c.  If it chooses c
     * then the notify is gone - either to some other
     * thread that is also waiting, or it is dropped
     * on the floor.
     *
     * a is what we expect.  b won't hurt us any -
     * callers should be programmed to handle
     * spurious wakeups.  In case of c,
     * then the interrupt has been cleared, but
     * we don't want to consume it.  It came from
     * user code and is intended for user code, not us.
     * So, we will remember that the interrupt has
     * occured and re-activate it when this thread
     * goes back into user code.
     * That being said, what do we do here?  Since
     * we could have been notified too, here we will
     * just pretend that we have been.  It won't hurt
     * anything to return in the same way as if
     * we were notified since callers have to be able to
     * handle spurious wakeups anyway.
     */
    if (error == JVMTI_ERROR_INTERRUPT) {
        handleInterrupt();
        error = JVMTI_ERROR_NONE;
    }
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor wait");
    }
}

void
debugMonitorTimedWait(jrawMonitorID monitor, jlong millis)
{
    jvmtiError error;
    error = FUNC_PTR(gdata->jvmti,RawMonitorWait)
        (gdata->jvmti, monitor, millis);
    if (error == JVMTI_ERROR_INTERRUPT) {
        /* See comment above */
        handleInterrupt();
        error = JVMTI_ERROR_NONE;
    }
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor timed wait");
    }
}

void
debugMonitorNotify(jrawMonitorID monitor)
{
    jvmtiError error;

    error = FUNC_PTR(gdata->jvmti,RawMonitorNotify)
                (gdata->jvmti, monitor);
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor notify");
    }
}

void
debugMonitorNotifyAll(jrawMonitorID monitor)
{
    jvmtiError error;

    error = FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
                (gdata->jvmti, monitor);
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on raw monitor notify all");
    }
}

jrawMonitorID
debugMonitorCreate(char *name)
{
    jrawMonitorID monitor;
    jvmtiError error;

    error = FUNC_PTR(gdata->jvmti,CreateRawMonitor)
                (gdata->jvmti, name, &monitor);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on creation of a raw monitor");
    }
    return monitor;
}

void
debugMonitorDestroy(jrawMonitorID monitor)
{
    jvmtiError error;

    error = FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
                (gdata->jvmti, monitor);
    error = ignore_vm_death(error);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on destruction of raw monitor");
    }
}

/**
 * Return array of all threads (must be inside a WITH_LOCAL_REFS)
 */
jthread *
allThreads(jint *count)
{
    jthread *threads;
    jvmtiError error;

    *count = 0;
    threads = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetAllThreads)
                (gdata->jvmti, count, &threads);
    if (error == AGENT_ERROR_OUT_OF_MEMORY) {
        return NULL; /* Let caller deal with no memory? */
    }
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "getting all threads");
    }
    return threads;
}

/**
 * Fill the passed in structure with thread group info.
 * name field is JVMTI allocated.  parent is global ref.
 */
void
threadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo *info)
{
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
                (gdata->jvmti, group, info);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on getting thread group info");
    }
}

/**
 * Return class signature string
 */
jvmtiError
classSignature(jclass clazz, char **psignature, char **pgeneric_signature)
{
    jvmtiError error;
    char *signature = NULL;

    /*
     * pgeneric_signature can be NULL, and GetClassSignature
     * accepts NULL.
     */
    error = FUNC_PTR(gdata->jvmti,GetClassSignature)
                (gdata->jvmti, clazz, &signature, pgeneric_signature);

    if ( psignature != NULL ) {
        *psignature = signature;
    } else if ( signature != NULL )  {
        jvmtiDeallocate(signature);
    }
    return error;
}

/* Get class name (not signature) */
char *
getClassname(jclass clazz)
{
    char *classname;

    classname = NULL;
    if ( clazz != NULL ) {
        if (classSignature(clazz, &classname, NULL) != JVMTI_ERROR_NONE) {
            classname = NULL;
        } else {
            /* Convert in place */
            convertSignatureToClassname(classname);
        }
    }
    return classname; /* Caller must free this memory */
}

void
writeGenericSignature(PacketOutputStream *out, char *genericSignature)
{
    if (genericSignature == NULL) {
        (void)outStream_writeString(out, "");
    } else {
        (void)outStream_writeString(out, genericSignature);
    }
}

jint
classStatus(jclass clazz)
{
    jint status;
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
                (gdata->jvmti, clazz, &status);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on getting class status");
    }
    return status;
}

static jboolean
isArrayClass(jclass clazz)
{
    jboolean isArray = JNI_FALSE;
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,IsArrayClass)
                (gdata->jvmti, clazz, &isArray);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on checking for an array class");
    }
    return isArray;
}

static jboolean
isInterface(jclass clazz)
{
    jboolean isInterface = JNI_FALSE;
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
                (gdata->jvmti, clazz, &isInterface);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on checking for an interface");
    }
    return isInterface;
}

jvmtiError
isFieldSynthetic(jclass clazz, jfieldID field, jboolean *psynthetic)
{
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,IsFieldSynthetic)
                (gdata->jvmti, clazz, field, psynthetic);
    if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
        /* If the query is not supported, we assume it is not synthetic. */
        *psynthetic = JNI_FALSE;
        return JVMTI_ERROR_NONE;
    }
    return error;
}

jvmtiError
isMethodSynthetic(jmethodID method, jboolean *psynthetic)
{
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodSynthetic)
                (gdata->jvmti, method, psynthetic);
    if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) {
        /* If the query is not supported, we assume it is not synthetic. */
        *psynthetic = JNI_FALSE;
        return JVMTI_ERROR_NONE;
    }
    return error;
}

jboolean
isMethodNative(jmethodID method)
{
    jboolean isNative = JNI_FALSE;
    jvmtiError error;

    error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
                (gdata->jvmti, method, &isNative);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "on checking for a native interface");
    }
    return isNative;
}

jboolean
isSameObject(JNIEnv *env, jobject o1, jobject o2)
{
    if ( o1==o2 ) {
        return JNI_TRUE;
    }
    return FUNC_PTR(env,IsSameObject)(env, o1, o2);
}

jint
objectHashCode(jobject object)
{
    jint hashCode = 0;
    jvmtiError error;

    if ( object!=NULL ) {
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectHashCode)
                    (gdata->jvmti, object, &hashCode);
        if (error != JVMTI_ERROR_NONE) {
            EXIT_ERROR(error, "on getting an object hash code");
        }
    }
    return hashCode;
}

/* Get all implemented interfaces (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allInterfaces(jclass clazz, jclass **ppinterfaces, jint *pcount)
{
    jvmtiError error;

    *pcount = 0;
    *ppinterfaces = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
                (gdata->jvmti, clazz, pcount, ppinterfaces);
    return error;
}

/* Get all loaded classes (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allLoadedClasses(jclass **ppclasses, jint *pcount)
{
    jvmtiError error;

    *pcount = 0;
    *ppclasses = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
                (gdata->jvmti, pcount, ppclasses);
    return error;
}

/* Get all loaded classes for a loader (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allClassLoaderClasses(jobject loader, jclass **ppclasses, jint *pcount)
{
    jvmtiError error;

    *pcount = 0;
    *ppclasses = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoaderClasses)
                (gdata->jvmti, loader, pcount, ppclasses);
    return error;
}

static jboolean
is_a_nested_class(char *outer_sig, int outer_sig_len, char *sig, int sep)
{
    char *inner;

    /* Assumed outer class signature is  "LOUTERCLASSNAME;"
     *         inner class signature is  "LOUTERCLASSNAME$INNERNAME;"
     *
     * INNERNAME can take the form:
     *    [0-9][1-9]*        anonymous class somewhere in the file
     *    [0-9][1-9]*NAME    local class somewhere in the OUTER class
     *    NAME               nested class in OUTER
     *
     * If NAME itself contains a $ (sep) then classname is further nested
     *    inside another class.
     *
     */

    /* Check prefix first */
    if ( strncmp(sig, outer_sig, outer_sig_len-1) != 0 ) {
        return JNI_FALSE;
    }

    /* Prefix must be followed by a $ (sep) */
    if ( sig[outer_sig_len-1] != sep ) {
        return JNI_FALSE;  /* No sep follows the match, must not be nested. */
    }

    /* Walk past any digits, if we reach the end, must be pure anonymous */
    inner = sig + outer_sig_len;
#if 1 /* We want to return local classes */
    while ( *inner && isdigit(*inner) ) {
        inner++;
    }
    /* But anonymous class names can't be trusted. */
    if ( *inner == ';' ) {
        return JNI_FALSE;  /* A pure anonymous class */
    }
#else
    if ( *inner && isdigit(*inner) ) {
        return JNI_FALSE;  /* A pure anonymous or local class */
    }
#endif

    /* Nested deeper? */
    if ( strchr(inner, sep) != NULL ) {
        return JNI_FALSE;  /* Nested deeper than we want? */
    }
    return JNI_TRUE;
}

/* Get all nested classes for a class (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allNestedClasses(jclass parent_clazz, jclass **ppnested, jint *pcount)
{
    jvmtiError error;
    jobject parent_loader;
    jclass *classes;
    char *signature;
    size_t len;
    jint count;
    jint ncount;
    int i;

    *ppnested   = NULL;
    *pcount     = 0;

    parent_loader = NULL;
    classes       = NULL;
    signature     = NULL;
    count         = 0;
    ncount        = 0;

    error = classLoader(parent_clazz, &parent_loader);
    if (error != JVMTI_ERROR_NONE) {
        return error;
    }
    error = classSignature(parent_clazz, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        return error;
    }
    len = strlen(signature);

    error = allClassLoaderClasses(parent_loader, &classes, &count);
    if ( error != JVMTI_ERROR_NONE ) {
        jvmtiDeallocate(signature);
        return error;
    }

    for (i=0; i<count; i++) {
        jclass clazz;
        char *candidate_signature;

        clazz = classes[i];
        candidate_signature = NULL;
        error = classSignature(clazz, &candidate_signature, NULL);
        if (error != JVMTI_ERROR_NONE) {
            break;
        }

        if ( is_a_nested_class(signature, (int)len, candidate_signature, '$') ||
             is_a_nested_class(signature, (int)len, candidate_signature, '#') ) {
            /* Float nested classes to top */
            classes[i] = classes[ncount];
            classes[ncount++] = clazz;
        }
        jvmtiDeallocate(candidate_signature);
    }

    jvmtiDeallocate(signature);

    if ( count != 0 &&  ncount == 0 ) {
        jvmtiDeallocate(classes);
        classes = NULL;
    }

    *ppnested = classes;
    *pcount = ncount;
    return error;
}

void
createLocalRefSpace(JNIEnv *env, jint capacity)
{
    /*
     * Save current exception since it might get overwritten by
     * the calls below. Note we must depend on space in the existing
     * frame because asking for a new frame may generate an exception.
     */
    jobject throwable = JNI_FUNC_PTR(env,ExceptionOccurred)(env);

    /*
     * Use the current frame if necessary; otherwise create a new one
     */
    if (JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity) < 0) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"PushLocalFrame: Unable to push JNI frame");
    }

    /*
     * TO DO: This could be more efficient if it used EnsureLocalCapacity,
     * but that would not work if two functions on the call stack
     * use this function. We would need to either track reserved
     * references on a per-thread basis or come up with a convention
     * that would prevent two functions from depending on this function
     * at the same time.
     */

    /*
     * Restore exception state from before call
     */
    if (throwable != NULL) {
        JNI_FUNC_PTR(env,Throw)(env, throwable);
    } else {
        JNI_FUNC_PTR(env,ExceptionClear)(env);
    }
}

jboolean
isClass(jobject object)
{
    JNIEnv *env = getEnv();
    return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass);
}

jboolean
isThread(jobject object)
{
    JNIEnv *env = getEnv();
    return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass);
}

jboolean
isThreadGroup(jobject object)
{
    JNIEnv *env = getEnv();
    return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass);
}

jboolean
isString(jobject object)
{
    JNIEnv *env = getEnv();
    return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass);
}

jboolean
isClassLoader(jobject object)
{
    JNIEnv *env = getEnv();
    return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass);
}

jboolean
isArray(jobject object)
{
    JNIEnv *env = getEnv();
    jboolean is;

    WITH_LOCAL_REFS(env, 1) {
        jclass clazz;
        clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
        is = isArrayClass(clazz);
    } END_WITH_LOCAL_REFS(env);

    return is;
}

/**
 * Return property value as jstring
 */
static jstring
getPropertyValue(JNIEnv *env, char *propertyName)
{
    jstring valueString;
    jstring nameString;

    valueString = NULL;

    /* Create new String object to hold the property name */
    nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
    if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
        JNI_FUNC_PTR(env,ExceptionClear)(env);
        /* NULL will be returned below */
    } else {
        /* Call valueString = System.getProperty(nameString) */
        valueString = JNI_FUNC_PTR(env,CallStaticObjectMethod)
            (env, gdata->systemClass, gdata->systemGetProperty, nameString);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            JNI_FUNC_PTR(env,ExceptionClear)(env);
            valueString = NULL;
        }
    }
    return valueString;
}

/**
 * Set an agent property
 */
void
setAgentPropertyValue(JNIEnv *env, char *propertyName, char* propertyValue)
{
    jstring nameString;
    jstring valueString;

    if (gdata->agent_properties == NULL) {
        /* VMSupport doesn't exist; so ignore */
        return;
    }

    /* Create jstrings for property name and value */
    nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName);
    if (nameString != NULL) {
        valueString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyValue);
        if (valueString != NULL) {
            /* invoke Properties.setProperty */
            JNI_FUNC_PTR(env,CallObjectMethod)
                (env, gdata->agent_properties,
                 gdata->setProperty,
                 nameString, valueString);
        }
    }
    if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
        JNI_FUNC_PTR(env,ExceptionClear)(env);
    }
}

/**
 * Return property value as JDWP allocated string in UTF8 encoding
 */
static char *
getPropertyUTF8(JNIEnv *env, char *propertyName)
{
    jvmtiError  error;
    char       *value;

    value = NULL;
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
                (gdata->jvmti, (const char *)propertyName, &value);
    if (error != JVMTI_ERROR_NONE) {
        jstring valueString;

        value = NULL;
        valueString = getPropertyValue(env, propertyName);

        if (valueString != NULL) {
            const char *utf;

            /* Get the UTF8 encoding for this property value string */
            utf = JNI_FUNC_PTR(env,GetStringUTFChars)(env, valueString, NULL);
            /* Make a copy for returning, release the JNI copy */
            value = jvmtiAllocate((int)strlen(utf) + 1);
            if (value != NULL) {
                (void)strcpy(value, utf);
            }
            JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, valueString, utf);
        }
    }
    if ( value == NULL ) {
        ERROR_MESSAGE(("JDWP Can't get property value for %s", propertyName));
        EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
    }
    return value;
}

jboolean
isMethodObsolete(jmethodID method)
{
    jvmtiError error;
    jboolean obsolete = JNI_TRUE;

    if ( method != NULL ) {
        error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodObsolete)
                    (gdata->jvmti, method, &obsolete);
        if (error != JVMTI_ERROR_NONE) {
            obsolete = JNI_TRUE;
        }
    }
    return obsolete;
}

/* Get the jvmti environment to be used with tags */
static jvmtiEnv *
getSpecialJvmti(void)
{
    jvmtiEnv  *jvmti;
    jvmtiError error;
    int        rc;

    /* Get one time use JVMTI Env */
    jvmtiCapabilities caps;

    rc = JVM_FUNC_PTR(gdata->jvm,GetEnv)
                     (gdata->jvm, (void **)&jvmti, JVMTI_VERSION_1);
    if (rc != JNI_OK) {
        return NULL;
    }
    (void)memset(&caps, 0, (int)sizeof(caps));
    caps.can_tag_objects = 1;
    error = JVMTI_FUNC_PTR(jvmti,AddCapabilities)(jvmti, &caps);
    if ( error != JVMTI_ERROR_NONE ) {
        return NULL;
    }
    return jvmti;
}

void
writeCodeLocation(PacketOutputStream *out, jclass clazz,
                       jmethodID method, jlocation location)
{
    jbyte tag;

    if (clazz != NULL) {
        tag = referenceTypeTag(clazz);
    } else {
        tag = JDWP_TYPE_TAG(CLASS);
    }
    (void)outStream_writeByte(out, tag);
    (void)outStream_writeObjectRef(getEnv(), out, clazz);
    (void)outStream_writeMethodID(out, isMethodObsolete(method)?NULL:method);
    (void)outStream_writeLocation(out, location);
}

void *
jvmtiAllocate(jint numBytes)
{
    void *ptr;
    jvmtiError error;
    if ( numBytes == 0 ) {
        return NULL;
    }
    error = FUNC_PTR(gdata->jvmti,Allocate)
                (gdata->jvmti, numBytes, (unsigned char**)&ptr);
    if (error != JVMTI_ERROR_NONE ) {
        EXIT_ERROR(error, "Can't allocate jvmti memory");
    }
    return ptr;
}

void
jvmtiDeallocate(void *ptr)
{
    jvmtiError error;
    if ( ptr == NULL ) {
        return;
    }
    error = FUNC_PTR(gdata->jvmti,Deallocate)
                (gdata->jvmti, ptr);
    if (error != JVMTI_ERROR_NONE ) {
        EXIT_ERROR(error, "Can't deallocate jvmti memory");
    }
}

/* Rarely needed, transport library uses JDWP errors, only use? */
jvmtiError
map2jvmtiError(jdwpError error)
{
    switch ( error ) {
        case JDWP_ERROR(NONE):
            return JVMTI_ERROR_NONE;
        case JDWP_ERROR(INVALID_THREAD):
            return JVMTI_ERROR_INVALID_THREAD;
        case JDWP_ERROR(INVALID_THREAD_GROUP):
            return JVMTI_ERROR_INVALID_THREAD_GROUP;
        case JDWP_ERROR(INVALID_PRIORITY):
            return JVMTI_ERROR_INVALID_PRIORITY;
        case JDWP_ERROR(THREAD_NOT_SUSPENDED):
            return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
        case JDWP_ERROR(THREAD_SUSPENDED):
            return JVMTI_ERROR_THREAD_SUSPENDED;
        case JDWP_ERROR(INVALID_OBJECT):
            return JVMTI_ERROR_INVALID_OBJECT;
        case JDWP_ERROR(INVALID_CLASS):
            return JVMTI_ERROR_INVALID_CLASS;
        case JDWP_ERROR(CLASS_NOT_PREPARED):
            return JVMTI_ERROR_CLASS_NOT_PREPARED;
        case JDWP_ERROR(INVALID_METHODID):
            return JVMTI_ERROR_INVALID_METHODID;
        case JDWP_ERROR(INVALID_LOCATION):
            return JVMTI_ERROR_INVALID_LOCATION;
        case JDWP_ERROR(INVALID_FIELDID):
            return JVMTI_ERROR_INVALID_FIELDID;
        case JDWP_ERROR(INVALID_FRAMEID):
            return AGENT_ERROR_INVALID_FRAMEID;
        case JDWP_ERROR(NO_MORE_FRAMES):
            return JVMTI_ERROR_NO_MORE_FRAMES;
        case JDWP_ERROR(OPAQUE_FRAME):
            return JVMTI_ERROR_OPAQUE_FRAME;
        case JDWP_ERROR(NOT_CURRENT_FRAME):
            return AGENT_ERROR_NOT_CURRENT_FRAME;
        case JDWP_ERROR(TYPE_MISMATCH):
            return JVMTI_ERROR_TYPE_MISMATCH;
        case JDWP_ERROR(INVALID_SLOT):
            return JVMTI_ERROR_INVALID_SLOT;
        case JDWP_ERROR(DUPLICATE):
            return JVMTI_ERROR_DUPLICATE;
        case JDWP_ERROR(NOT_FOUND):
            return JVMTI_ERROR_NOT_FOUND;
        case JDWP_ERROR(INVALID_MONITOR):
            return JVMTI_ERROR_INVALID_MONITOR;
        case JDWP_ERROR(NOT_MONITOR_OWNER):
            return JVMTI_ERROR_NOT_MONITOR_OWNER;
        case JDWP_ERROR(INTERRUPT):
            return JVMTI_ERROR_INTERRUPT;
        case JDWP_ERROR(INVALID_CLASS_FORMAT):
            return JVMTI_ERROR_INVALID_CLASS_FORMAT;
        case JDWP_ERROR(CIRCULAR_CLASS_DEFINITION):
            return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
        case JDWP_ERROR(FAILS_VERIFICATION):
            return JVMTI_ERROR_FAILS_VERIFICATION;
        case JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
        case JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
        case JDWP_ERROR(INVALID_TYPESTATE):
            return JVMTI_ERROR_INVALID_TYPESTATE;
        case JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
        case JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
        case JDWP_ERROR(UNSUPPORTED_VERSION):
            return JVMTI_ERROR_UNSUPPORTED_VERSION;
        case JDWP_ERROR(NAMES_DONT_MATCH):
            return JVMTI_ERROR_NAMES_DONT_MATCH;
        case JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
        case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED):
            return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
        case JDWP_ERROR(NOT_IMPLEMENTED):
            return JVMTI_ERROR_NOT_AVAILABLE;
        case JDWP_ERROR(NULL_POINTER):
            return JVMTI_ERROR_NULL_POINTER;
        case JDWP_ERROR(ABSENT_INFORMATION):
            return JVMTI_ERROR_ABSENT_INFORMATION;
        case JDWP_ERROR(INVALID_EVENT_TYPE):
            return JVMTI_ERROR_INVALID_EVENT_TYPE;
        case JDWP_ERROR(ILLEGAL_ARGUMENT):
            return JVMTI_ERROR_ILLEGAL_ARGUMENT;
        case JDWP_ERROR(OUT_OF_MEMORY):
            return JVMTI_ERROR_OUT_OF_MEMORY;
        case JDWP_ERROR(ACCESS_DENIED):
            return JVMTI_ERROR_ACCESS_DENIED;
        case JDWP_ERROR(VM_DEAD):
            return JVMTI_ERROR_WRONG_PHASE;
        case JDWP_ERROR(UNATTACHED_THREAD):
            return JVMTI_ERROR_UNATTACHED_THREAD;
        case JDWP_ERROR(INVALID_TAG):
            return AGENT_ERROR_INVALID_TAG;
        case JDWP_ERROR(ALREADY_INVOKING):
            return AGENT_ERROR_ALREADY_INVOKING;
        case JDWP_ERROR(INVALID_INDEX):
            return AGENT_ERROR_INVALID_INDEX;
        case JDWP_ERROR(INVALID_LENGTH):
            return AGENT_ERROR_INVALID_LENGTH;
        case JDWP_ERROR(INVALID_STRING):
            return AGENT_ERROR_INVALID_STRING;
        case JDWP_ERROR(INVALID_CLASS_LOADER):
            return AGENT_ERROR_INVALID_CLASS_LOADER;
        case JDWP_ERROR(INVALID_ARRAY):
            return AGENT_ERROR_INVALID_ARRAY;
        case JDWP_ERROR(TRANSPORT_LOAD):
            return AGENT_ERROR_TRANSPORT_LOAD;
        case JDWP_ERROR(TRANSPORT_INIT):
            return AGENT_ERROR_TRANSPORT_INIT;
        case JDWP_ERROR(NATIVE_METHOD):
            return AGENT_ERROR_NATIVE_METHOD;
        case JDWP_ERROR(INVALID_COUNT):
            return AGENT_ERROR_INVALID_COUNT;
        case JDWP_ERROR(INTERNAL):
            return AGENT_ERROR_JDWP_INTERNAL;
    }
    return AGENT_ERROR_INTERNAL;
}

static jvmtiEvent index2jvmti[EI_max-EI_min+1];
static jdwpEvent  index2jdwp [EI_max-EI_min+1];

void
eventIndexInit(void)
{
    (void)memset(index2jvmti, 0, (int)sizeof(index2jvmti));
    (void)memset(index2jdwp,  0, (int)sizeof(index2jdwp));

    index2jvmti[EI_SINGLE_STEP        -EI_min] = JVMTI_EVENT_SINGLE_STEP;
    index2jvmti[EI_BREAKPOINT         -EI_min] = JVMTI_EVENT_BREAKPOINT;
    index2jvmti[EI_FRAME_POP          -EI_min] = JVMTI_EVENT_FRAME_POP;
    index2jvmti[EI_EXCEPTION          -EI_min] = JVMTI_EVENT_EXCEPTION;
    index2jvmti[EI_THREAD_START       -EI_min] = JVMTI_EVENT_THREAD_START;
    index2jvmti[EI_THREAD_END         -EI_min] = JVMTI_EVENT_THREAD_END;
    index2jvmti[EI_CLASS_PREPARE      -EI_min] = JVMTI_EVENT_CLASS_PREPARE;
    index2jvmti[EI_GC_FINISH          -EI_min] = JVMTI_EVENT_GARBAGE_COLLECTION_FINISH;
    index2jvmti[EI_CLASS_LOAD         -EI_min] = JVMTI_EVENT_CLASS_LOAD;
    index2jvmti[EI_FIELD_ACCESS       -EI_min] = JVMTI_EVENT_FIELD_ACCESS;
    index2jvmti[EI_FIELD_MODIFICATION -EI_min] = JVMTI_EVENT_FIELD_MODIFICATION;
    index2jvmti[EI_EXCEPTION_CATCH    -EI_min] = JVMTI_EVENT_EXCEPTION_CATCH;
    index2jvmti[EI_METHOD_ENTRY       -EI_min] = JVMTI_EVENT_METHOD_ENTRY;
    index2jvmti[EI_METHOD_EXIT        -EI_min] = JVMTI_EVENT_METHOD_EXIT;
    index2jvmti[EI_MONITOR_CONTENDED_ENTER      -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTER;
    index2jvmti[EI_MONITOR_CONTENDED_ENTERED    -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED;
    index2jvmti[EI_MONITOR_WAIT       -EI_min] = JVMTI_EVENT_MONITOR_WAIT;
    index2jvmti[EI_MONITOR_WAITED     -EI_min] = JVMTI_EVENT_MONITOR_WAITED;
    index2jvmti[EI_VM_INIT            -EI_min] = JVMTI_EVENT_VM_INIT;
    index2jvmti[EI_VM_DEATH           -EI_min] = JVMTI_EVENT_VM_DEATH;

    index2jdwp[EI_SINGLE_STEP         -EI_min] = JDWP_EVENT(SINGLE_STEP);
    index2jdwp[EI_BREAKPOINT          -EI_min] = JDWP_EVENT(BREAKPOINT);
    index2jdwp[EI_FRAME_POP           -EI_min] = JDWP_EVENT(FRAME_POP);
    index2jdwp[EI_EXCEPTION           -EI_min] = JDWP_EVENT(EXCEPTION);
    index2jdwp[EI_THREAD_START        -EI_min] = JDWP_EVENT(THREAD_START);
    index2jdwp[EI_THREAD_END          -EI_min] = JDWP_EVENT(THREAD_END);
    index2jdwp[EI_CLASS_PREPARE       -EI_min] = JDWP_EVENT(CLASS_PREPARE);
    index2jdwp[EI_GC_FINISH           -EI_min] = JDWP_EVENT(CLASS_UNLOAD);
    index2jdwp[EI_CLASS_LOAD          -EI_min] = JDWP_EVENT(CLASS_LOAD);
    index2jdwp[EI_FIELD_ACCESS        -EI_min] = JDWP_EVENT(FIELD_ACCESS);
    index2jdwp[EI_FIELD_MODIFICATION  -EI_min] = JDWP_EVENT(FIELD_MODIFICATION);
    index2jdwp[EI_EXCEPTION_CATCH     -EI_min] = JDWP_EVENT(EXCEPTION_CATCH);
    index2jdwp[EI_METHOD_ENTRY        -EI_min] = JDWP_EVENT(METHOD_ENTRY);
    index2jdwp[EI_METHOD_EXIT         -EI_min] = JDWP_EVENT(METHOD_EXIT);
    index2jdwp[EI_MONITOR_CONTENDED_ENTER             -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTER);
    index2jdwp[EI_MONITOR_CONTENDED_ENTERED           -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTERED);
    index2jdwp[EI_MONITOR_WAIT        -EI_min] = JDWP_EVENT(MONITOR_WAIT);
    index2jdwp[EI_MONITOR_WAITED      -EI_min] = JDWP_EVENT(MONITOR_WAITED);
    index2jdwp[EI_VM_INIT             -EI_min] = JDWP_EVENT(VM_INIT);
    index2jdwp[EI_VM_DEATH            -EI_min] = JDWP_EVENT(VM_DEATH);
}

jdwpEvent
eventIndex2jdwp(EventIndex i)
{
    if ( i < EI_min || i > EI_max ) {
        EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
    }
    return index2jdwp[i-EI_min];
}

jvmtiEvent
eventIndex2jvmti(EventIndex i)
{
    if ( i < EI_min || i > EI_max ) {
        EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex");
    }
    return index2jvmti[i-EI_min];
}

EventIndex
jdwp2EventIndex(jdwpEvent eventType)
{
    switch ( eventType ) {
        case JDWP_EVENT(SINGLE_STEP):
            return EI_SINGLE_STEP;
        case JDWP_EVENT(BREAKPOINT):
            return EI_BREAKPOINT;
        case JDWP_EVENT(FRAME_POP):
            return EI_FRAME_POP;
        case JDWP_EVENT(EXCEPTION):
            return EI_EXCEPTION;
        case JDWP_EVENT(THREAD_START):
            return EI_THREAD_START;
        case JDWP_EVENT(THREAD_END):
            return EI_THREAD_END;
        case JDWP_EVENT(CLASS_PREPARE):
            return EI_CLASS_PREPARE;
        case JDWP_EVENT(CLASS_UNLOAD):
            return EI_GC_FINISH;
        case JDWP_EVENT(CLASS_LOAD):
            return EI_CLASS_LOAD;
        case JDWP_EVENT(FIELD_ACCESS):
            return EI_FIELD_ACCESS;
        case JDWP_EVENT(FIELD_MODIFICATION):
            return EI_FIELD_MODIFICATION;
        case JDWP_EVENT(EXCEPTION_CATCH):
            return EI_EXCEPTION_CATCH;
        case JDWP_EVENT(METHOD_ENTRY):
            return EI_METHOD_ENTRY;
        case JDWP_EVENT(METHOD_EXIT):
            return EI_METHOD_EXIT;
        case JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE):
            return EI_METHOD_EXIT;
        case JDWP_EVENT(MONITOR_CONTENDED_ENTER):
            return EI_MONITOR_CONTENDED_ENTER;
        case JDWP_EVENT(MONITOR_CONTENDED_ENTERED):
            return EI_MONITOR_CONTENDED_ENTERED;
        case JDWP_EVENT(MONITOR_WAIT):
            return EI_MONITOR_WAIT;
        case JDWP_EVENT(MONITOR_WAITED):
            return EI_MONITOR_WAITED;
        case JDWP_EVENT(VM_INIT):
            return EI_VM_INIT;
        case JDWP_EVENT(VM_DEATH):
            return EI_VM_DEATH;
        default:
            break;
    }

    /*
     * Event type not recognized - don't exit with error as caller
     * may wish to return error to debugger.
     */
    return (EventIndex)0;
}

EventIndex
jvmti2EventIndex(jvmtiEvent kind)
{
    switch ( kind ) {
        case JVMTI_EVENT_SINGLE_STEP:
            return EI_SINGLE_STEP;
        case JVMTI_EVENT_BREAKPOINT:
            return EI_BREAKPOINT;
        case JVMTI_EVENT_FRAME_POP:
            return EI_FRAME_POP;
        case JVMTI_EVENT_EXCEPTION:
            return EI_EXCEPTION;
        case JVMTI_EVENT_THREAD_START:
            return EI_THREAD_START;
        case JVMTI_EVENT_THREAD_END:
            return EI_THREAD_END;
        case JVMTI_EVENT_CLASS_PREPARE:
            return EI_CLASS_PREPARE;
        case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
            return EI_GC_FINISH;
        case JVMTI_EVENT_CLASS_LOAD:
            return EI_CLASS_LOAD;
        case JVMTI_EVENT_FIELD_ACCESS:
            return EI_FIELD_ACCESS;
        case JVMTI_EVENT_FIELD_MODIFICATION:
            return EI_FIELD_MODIFICATION;
        case JVMTI_EVENT_EXCEPTION_CATCH:
            return EI_EXCEPTION_CATCH;
        case JVMTI_EVENT_METHOD_ENTRY:
            return EI_METHOD_ENTRY;
        case JVMTI_EVENT_METHOD_EXIT:
            return EI_METHOD_EXIT;
        /*
         * There is no JVMTI_EVENT_METHOD_EXIT_WITH_RETURN_VALUE.
         * The normal JVMTI_EVENT_METHOD_EXIT always contains the return value.
         */
        case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
            return EI_MONITOR_CONTENDED_ENTER;
        case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
            return EI_MONITOR_CONTENDED_ENTERED;
        case JVMTI_EVENT_MONITOR_WAIT:
            return EI_MONITOR_WAIT;
        case JVMTI_EVENT_MONITOR_WAITED:
            return EI_MONITOR_WAITED;
        case JVMTI_EVENT_VM_INIT:
            return EI_VM_INIT;
        case JVMTI_EVENT_VM_DEATH:
            return EI_VM_DEATH;
        default:
            EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"JVMTI to EventIndex mapping");
            break;
    }
    return (EventIndex)0;
}

/* This routine is commonly used, maps jvmti and agent errors to the best
 *    jdwp error code we can map to.
 */
jdwpError
map2jdwpError(jvmtiError error)
{
    switch ( error ) {
        case JVMTI_ERROR_NONE:
            return JDWP_ERROR(NONE);
        case AGENT_ERROR_INVALID_THREAD:
        case JVMTI_ERROR_INVALID_THREAD:
            return JDWP_ERROR(INVALID_THREAD);
        case JVMTI_ERROR_INVALID_THREAD_GROUP:
            return JDWP_ERROR(INVALID_THREAD_GROUP);
        case JVMTI_ERROR_INVALID_PRIORITY:
            return JDWP_ERROR(INVALID_PRIORITY);
        case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
            return JDWP_ERROR(THREAD_NOT_SUSPENDED);
        case JVMTI_ERROR_THREAD_SUSPENDED:
            return JDWP_ERROR(THREAD_SUSPENDED);
        case JVMTI_ERROR_THREAD_NOT_ALIVE:
            return JDWP_ERROR(INVALID_THREAD);
        case AGENT_ERROR_INVALID_OBJECT:
        case JVMTI_ERROR_INVALID_OBJECT:
            return JDWP_ERROR(INVALID_OBJECT);
        case JVMTI_ERROR_INVALID_CLASS:
            return JDWP_ERROR(INVALID_CLASS);
        case JVMTI_ERROR_CLASS_NOT_PREPARED:
            return JDWP_ERROR(CLASS_NOT_PREPARED);
        case JVMTI_ERROR_INVALID_METHODID:
            return JDWP_ERROR(INVALID_METHODID);
        case JVMTI_ERROR_INVALID_LOCATION:
            return JDWP_ERROR(INVALID_LOCATION);
        case JVMTI_ERROR_INVALID_FIELDID:
            return JDWP_ERROR(INVALID_FIELDID);
        case AGENT_ERROR_NO_MORE_FRAMES:
        case JVMTI_ERROR_NO_MORE_FRAMES:
            return JDWP_ERROR(NO_MORE_FRAMES);
        case JVMTI_ERROR_OPAQUE_FRAME:
            return JDWP_ERROR(OPAQUE_FRAME);
        case JVMTI_ERROR_TYPE_MISMATCH:
            return JDWP_ERROR(TYPE_MISMATCH);
        case JVMTI_ERROR_INVALID_SLOT:
            return JDWP_ERROR(INVALID_SLOT);
        case JVMTI_ERROR_DUPLICATE:
            return JDWP_ERROR(DUPLICATE);
        case JVMTI_ERROR_NOT_FOUND:
            return JDWP_ERROR(NOT_FOUND);
        case JVMTI_ERROR_INVALID_MONITOR:
            return JDWP_ERROR(INVALID_MONITOR);
        case JVMTI_ERROR_NOT_MONITOR_OWNER:
            return JDWP_ERROR(NOT_MONITOR_OWNER);
        case JVMTI_ERROR_INTERRUPT:
            return JDWP_ERROR(INTERRUPT);
        case JVMTI_ERROR_INVALID_CLASS_FORMAT:
            return JDWP_ERROR(INVALID_CLASS_FORMAT);
        case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
            return JDWP_ERROR(CIRCULAR_CLASS_DEFINITION);
        case JVMTI_ERROR_FAILS_VERIFICATION:
            return JDWP_ERROR(FAILS_VERIFICATION);
        case JVMTI_ERROR_INVALID_TYPESTATE:
            return JDWP_ERROR(INVALID_TYPESTATE);
        case JVMTI_ERROR_UNSUPPORTED_VERSION:
            return JDWP_ERROR(UNSUPPORTED_VERSION);
        case JVMTI_ERROR_NAMES_DONT_MATCH:
            return JDWP_ERROR(NAMES_DONT_MATCH);
        case AGENT_ERROR_NULL_POINTER:
        case JVMTI_ERROR_NULL_POINTER:
            return JDWP_ERROR(NULL_POINTER);
        case JVMTI_ERROR_ABSENT_INFORMATION:
            return JDWP_ERROR(ABSENT_INFORMATION);
        case AGENT_ERROR_INVALID_EVENT_TYPE:
        case JVMTI_ERROR_INVALID_EVENT_TYPE:
            return JDWP_ERROR(INVALID_EVENT_TYPE);
        case AGENT_ERROR_ILLEGAL_ARGUMENT:
        case JVMTI_ERROR_ILLEGAL_ARGUMENT:
            return JDWP_ERROR(ILLEGAL_ARGUMENT);
        case JVMTI_ERROR_OUT_OF_MEMORY:
        case AGENT_ERROR_OUT_OF_MEMORY:
            return JDWP_ERROR(OUT_OF_MEMORY);
        case JVMTI_ERROR_ACCESS_DENIED:
            return JDWP_ERROR(ACCESS_DENIED);
        case JVMTI_ERROR_WRONG_PHASE:
        case AGENT_ERROR_VM_DEAD:
        case AGENT_ERROR_NO_JNI_ENV:
            return JDWP_ERROR(VM_DEAD);
        case AGENT_ERROR_JNI_EXCEPTION:
        case JVMTI_ERROR_UNATTACHED_THREAD:
            return JDWP_ERROR(UNATTACHED_THREAD);
        case JVMTI_ERROR_NOT_AVAILABLE:
        case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
            return JDWP_ERROR(NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
            return JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
            return JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
            return JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
            return JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
            return JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
        case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
            return JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED);
        case AGENT_ERROR_NOT_CURRENT_FRAME:
            return JDWP_ERROR(NOT_CURRENT_FRAME);
        case AGENT_ERROR_INVALID_TAG:
            return JDWP_ERROR(INVALID_TAG);
        case AGENT_ERROR_ALREADY_INVOKING:
            return JDWP_ERROR(ALREADY_INVOKING);
        case AGENT_ERROR_INVALID_INDEX:
            return JDWP_ERROR(INVALID_INDEX);
        case AGENT_ERROR_INVALID_LENGTH:
            return JDWP_ERROR(INVALID_LENGTH);
        case AGENT_ERROR_INVALID_STRING:
            return JDWP_ERROR(INVALID_STRING);
        case AGENT_ERROR_INVALID_CLASS_LOADER:
            return JDWP_ERROR(INVALID_CLASS_LOADER);
        case AGENT_ERROR_INVALID_ARRAY:
            return JDWP_ERROR(INVALID_ARRAY);
        case AGENT_ERROR_TRANSPORT_LOAD:
            return JDWP_ERROR(TRANSPORT_LOAD);
        case AGENT_ERROR_TRANSPORT_INIT:
            return JDWP_ERROR(TRANSPORT_INIT);
        case AGENT_ERROR_NATIVE_METHOD:
            return JDWP_ERROR(NATIVE_METHOD);
        case AGENT_ERROR_INVALID_COUNT:
            return JDWP_ERROR(INVALID_COUNT);
        case AGENT_ERROR_INVALID_FRAMEID:
            return JDWP_ERROR(INVALID_FRAMEID);
        case JVMTI_ERROR_INTERNAL:
        case JVMTI_ERROR_INVALID_ENVIRONMENT:
        case AGENT_ERROR_INTERNAL:
        case AGENT_ERROR_JVMTI_INTERNAL:
        case AGENT_ERROR_JDWP_INTERNAL:
            return JDWP_ERROR(INTERNAL);
        default:
            break;
    }
    return JDWP_ERROR(INTERNAL);
}

jint
map2jdwpSuspendStatus(jint state)
{
    jint status = 0;
    if ( ( state & JVMTI_THREAD_STATE_SUSPENDED ) != 0 )  {
        status = JDWP_SUSPEND_STATUS(SUSPENDED);
    }
    return status;
}

jdwpThreadStatus
map2jdwpThreadStatus(jint state)
{
    jdwpThreadStatus status;

    status = (jdwpThreadStatus)(-1);

    if ( ! ( state & JVMTI_THREAD_STATE_ALIVE ) ) {
        if ( state & JVMTI_THREAD_STATE_TERMINATED ) {
            status = JDWP_THREAD_STATUS(ZOMBIE);
        } else {
            /* FIXUP? New JDWP #define for not started? */
            status = (jdwpThreadStatus)(-1);
        }
    } else {
        if ( state & JVMTI_THREAD_STATE_SLEEPING ) {
            status = JDWP_THREAD_STATUS(SLEEPING);
        } else if ( state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
            status = JDWP_THREAD_STATUS(MONITOR);
        } else if ( state & JVMTI_THREAD_STATE_WAITING ) {
            status = JDWP_THREAD_STATUS(WAIT);
        } else if ( state & JVMTI_THREAD_STATE_RUNNABLE ) {
            status = JDWP_THREAD_STATUS(RUNNING);
        }
    }
    return status;
}

jint
map2jdwpClassStatus(jint classStatus)
{
    jint status = 0;
    if ( ( classStatus & JVMTI_CLASS_STATUS_VERIFIED ) != 0 ) {
        status |= JDWP_CLASS_STATUS(VERIFIED);
    }
    if ( ( classStatus & JVMTI_CLASS_STATUS_PREPARED ) != 0 ) {
        status |= JDWP_CLASS_STATUS(PREPARED);
    }
    if ( ( classStatus & JVMTI_CLASS_STATUS_INITIALIZED ) != 0 ) {
        status |= JDWP_CLASS_STATUS(INITIALIZED);
    }
    if ( ( classStatus & JVMTI_CLASS_STATUS_ERROR ) != 0 ) {
        status |= JDWP_CLASS_STATUS(ERROR);
    }
    return status;
}

void
log_debugee_location(const char *func,
        jthread thread, jmethodID method, jlocation location)
{
    int logging_locations = LOG_TEST(JDWP_LOG_LOC);

    if ( logging_locations ) {
        char *method_name;
        char *class_sig;
        jvmtiError error;
        jvmtiThreadInfo info;
        jint state;

        /* Get thread information */
        info.name = NULL;
        error = FUNC_PTR(gdata->jvmti,GetThreadInfo)
                                (gdata->jvmti, thread, &info);
        if ( error != JVMTI_ERROR_NONE) {
            info.name = NULL;
        }
        error = FUNC_PTR(gdata->jvmti,GetThreadState)
                                (gdata->jvmti, thread, &state);
        if ( error != JVMTI_ERROR_NONE) {
            state = 0;
        }

        /* Get method if necessary */
        if ( method==NULL ) {
            error = FUNC_PTR(gdata->jvmti,GetFrameLocation)
                        (gdata->jvmti, thread, 0, &method, &location);
            if ( error != JVMTI_ERROR_NONE ) {
                method = NULL;
                location = 0;
            }
        }

        /* Get method name */
        method_name = NULL;
        if ( method != NULL ) {
            error = methodSignature(method, &method_name, NULL, NULL);
            if ( error != JVMTI_ERROR_NONE ) {
                method_name = NULL;
            }
        }

        /* Get class signature */
        class_sig = NULL;
        if ( method != NULL ) {
            jclass clazz;

            error = methodClass(method, &clazz);
            if ( error == JVMTI_ERROR_NONE ) {
                error = classSignature(clazz, &class_sig, NULL);
                if ( error != JVMTI_ERROR_NONE ) {
                    class_sig = NULL;
                }
            }
        }

        /* Issue log message */
        LOG_LOC(("%s: debugee: thread=%p(%s:0x%x),method=%p(%s@%d;%s)",
                func,
                thread, info.name==NULL ? "?" : info.name, state,
                method, method_name==NULL ? "?" : method_name,
                (int)location, class_sig==NULL ? "?" : class_sig));

        /* Free memory */
        if ( class_sig != NULL ) {
            jvmtiDeallocate(class_sig);
        }
        if ( method_name != NULL ) {
            jvmtiDeallocate(method_name);
        }
        if ( info.name != NULL ) {
            jvmtiDeallocate(info.name);
        }
    }
}

/* ********************************************************************* */
/* JDK 6.0: Use of new Heap Iteration functions */
/* ********************************************************************* */

/* ********************************************************************* */
/* Instances */

/* Structure to hold class instances heap iteration data (arg user_data) */
typedef struct ClassInstancesData {
    jint         instCount;
    jint         maxInstances;
    jlong        objTag;
    jvmtiError   error;
} ClassInstancesData;

/* Callback for instance object tagging (heap_reference_callback). */
static jint JNICALL
cbObjectTagInstance(jvmtiHeapReferenceKind reference_kind,
     const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
     jlong referrer_class_tag, jlong size,
     jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
{
    ClassInstancesData  *data;

    /* Check data structure */
    data = (ClassInstancesData*)user_data;
    if (data == NULL) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* If we have tagged enough objects, just abort */
    if ( data->maxInstances != 0 && data->instCount >= data->maxInstances ) {
        return JVMTI_VISIT_ABORT;
    }

    /* If tagged already, just continue */
    if ( (*tag_ptr) != (jlong)0 ) {
        return JVMTI_VISIT_OBJECTS;
    }

    /* Tag the object so we don't count it again, and so we can retrieve it */
    (*tag_ptr) = data->objTag;
    data->instCount++;
    return JVMTI_VISIT_OBJECTS;
}

/* Get instances for one class */
jvmtiError
classInstances(jclass klass, ObjectBatch *instances, int maxInstances)
{
    ClassInstancesData data;
    jvmtiHeapCallbacks heap_callbacks;
    jvmtiError         error;
    jvmtiEnv          *jvmti;

    /* Check interface assumptions */

    if (klass == NULL) {
        return AGENT_ERROR_INVALID_OBJECT;
    }

    if ( maxInstances < 0 || instances == NULL) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Initialize return information */
    instances->count   = 0;
    instances->objects = NULL;

    /* Get jvmti environment to use */
    jvmti = getSpecialJvmti();
    if ( jvmti == NULL ) {
        return AGENT_ERROR_INTERNAL;
    }

    /* Setup data to passed around the callbacks */
    data.instCount    = 0;
    data.maxInstances = maxInstances;
    data.objTag       = (jlong)1;
    data.error        = JVMTI_ERROR_NONE;

    /* Clear out callbacks structure */
    (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));

    /* Set the callbacks we want */
    heap_callbacks.heap_reference_callback = &cbObjectTagInstance;

    /* Follow references, no initiating object, just this class, all objects */
    error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
                 (jvmti, 0, klass, NULL, &heap_callbacks, &data);
    if ( error == JVMTI_ERROR_NONE ) {
        error = data.error;
    }

    /* Get all the instances now that they are tagged */
    if ( error == JVMTI_ERROR_NONE ) {
        error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
                      (jvmti, 1, &(data.objTag), &(instances->count),
                       &(instances->objects), NULL);
        /* Verify we got the count we expected */
        if ( data.instCount != instances->count ) {
            error = AGENT_ERROR_INTERNAL;
        }
    }

    /* Dispose of any special jvmti environment */
    (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
    return error;
}

/* ********************************************************************* */
/* Instance counts. */

/* Macros to convert a class or instance tag to an index and back again */
#define INDEX2CLASSTAG(i)      ((jlong)((i)+1))
#define CLASSTAG2INDEX(t)      (((int)(t))-1)
#define JLONG_ABS(x)           (((x)<(jlong)0)?-(x):(x))

/* Structure to hold class count heap traversal data (arg user_data) */
typedef struct ClassCountData {
    int          classCount;
    jlong       *counts;
    jlong        negObjTag;
    jvmtiError   error;
} ClassCountData;

/* Two different cbObjectCounter's, one for FollowReferences, one for
 *    IterateThroughHeap. Pick a card, any card.
 */

/* Callback for object count heap traversal (heap_reference_callback) */
static jint JNICALL
cbObjectCounterFromRef(jvmtiHeapReferenceKind reference_kind,
     const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
     jlong referrer_class_tag, jlong size,
     jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
{
    ClassCountData  *data;
    int              index;
    jlong            jindex;
    jlong            tag;

    /* Check data structure */
    data = (ClassCountData*)user_data;
    if (data == NULL) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* Classes with no class_tag should have been filtered out. */
    if ( class_tag == (jlong)0 ) {
        data->error = AGENT_ERROR_INTERNAL;
        return JVMTI_VISIT_ABORT;
    }

    /* Class tag not one we really want (jclass not in supplied list) */
    if ( class_tag == data->negObjTag ) {
        return JVMTI_VISIT_OBJECTS;
    }

    /* If object tag is negative, just continue, we counted it */
    tag = (*tag_ptr);
    if ( tag < (jlong)0 ) {
        return JVMTI_VISIT_OBJECTS;
    }

    /* Tag the object with a negative value just so we don't count it again */
    if ( tag == (jlong)0 ) {
        /* This object had no tag value, so we give it the negObjTag value */
        (*tag_ptr) = data->negObjTag;
    } else {
        /* If this object had a positive tag value, it must be one of the
         *    jclass objects we tagged. We need to preserve the value of
         *    this tag for later objects that might have this as a class
         *    tag, so we just make the existing tag value negative.
         */
        (*tag_ptr) = -tag;
    }

    /* Absolute value of class tag is an index into the counts[] array */
    jindex = JLONG_ABS(class_tag);
    index = CLASSTAG2INDEX(jindex);
    if (index < 0 || index >= data->classCount) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* Bump instance count on this class */
    data->counts[index]++;
    return JVMTI_VISIT_OBJECTS;
}

/* Callback for instance count heap traversal (heap_iteration_callback) */
static jint JNICALL
cbObjectCounter(jlong class_tag, jlong size, jlong* tag_ptr, jint length,
                        void* user_data)
{
    ClassCountData  *data;
    int              index;

    /* Check data structure */
    data = (ClassCountData*)user_data;
    if (data == NULL) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* Classes with no tag should be filtered out. */
    if ( class_tag == (jlong)0 ) {
        data->error = AGENT_ERROR_INTERNAL;
        return JVMTI_VISIT_ABORT;
    }

    /* Class tag is actually an index into data arrays */
    index = CLASSTAG2INDEX(class_tag);
    if (index < 0 || index >= data->classCount) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* Bump instance count on this class */
    data->counts[index]++;
    return JVMTI_VISIT_OBJECTS;
}

/* Get instance counts for a set of classes */
jvmtiError
classInstanceCounts(jint classCount, jclass *classes, jlong *counts)
{
    jvmtiHeapCallbacks heap_callbacks;
    ClassCountData     data;
    jvmtiError         error;
    jvmtiEnv          *jvmti;
    int                i;

    /* Check interface assumptions */
    if ( classes == NULL || classCount <= 0 || counts == NULL ) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Initialize return information */
    for ( i = 0 ; i < classCount ; i++ ) {
        counts[i] = (jlong)0;
    }

    /* Get jvmti environment to use */
    jvmti = getSpecialJvmti();
    if ( jvmti == NULL ) {
        return AGENT_ERROR_INTERNAL;
    }

    /* Setup class data structure */
    data.error        = JVMTI_ERROR_NONE;
    data.classCount   = classCount;
    data.counts       = counts;

    error = JVMTI_ERROR_NONE;
    /* Set tags on classes, use index in classes[] as the tag value. */
    error             = JVMTI_ERROR_NONE;
    for ( i = 0 ; i < classCount ; i++ ) {
        if (classes[i] != NULL) {
            jlong tag;

            tag = INDEX2CLASSTAG(i);
            error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, classes[i], tag);
            if ( error != JVMTI_ERROR_NONE ) {
                break;
            }
        }
    }

    /* Traverse heap, two ways to do this for instance counts. */
    if ( error == JVMTI_ERROR_NONE ) {

        /* Clear out callbacks structure */
        (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));

        /* Check debug flags to see how to do this. */
        if ( (gdata->debugflags & USE_ITERATE_THROUGH_HEAP) == 0 ) {

            /* Using FollowReferences only gives us live objects, but we
             *   need to tag the objects to avoid counting them twice since
             *   the callback is per reference.
             *   The jclass objects have been tagged with their index in the
             *   supplied list, and that tag may flip to negative if it
             *   is also an object of interest.
             *   All other objects being counted that weren't in the
             *   supplied classes list will have a negative classCount
             *   tag value. So all objects counted will have negative tags.
             *   If the absolute tag value is an index in the supplied
             *   list, then it's one of the supplied classes.
             */
            data.negObjTag = -INDEX2CLASSTAG(classCount);

            /* Setup callbacks, only using object reference callback */
            heap_callbacks.heap_reference_callback = &cbObjectCounterFromRef;

            /* Follow references, no initiating object, tagged classes only */
            error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
                          (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
                           NULL, NULL, &heap_callbacks, &data);

        } else {

            /* Using IterateThroughHeap means that we will visit each object
             *   once, so no special tag tricks here. Just simple counting.
             *   However in this case the object might not be live, so we do
             *   a GC beforehand to make sure we minimize this.
             */

            /* FIXUP: Need some kind of trigger here to avoid excessive GC's? */
            error = JVMTI_FUNC_PTR(jvmti,ForceGarbageCollection)(jvmti);
            if ( error != JVMTI_ERROR_NONE ) {

                /* Setup callbacks, just need object callback */
                heap_callbacks.heap_iteration_callback = &cbObjectCounter;

                /* Iterate through entire heap, tagged classes only */
                error = JVMTI_FUNC_PTR(jvmti,IterateThroughHeap)
                              (jvmti, JVMTI_HEAP_FILTER_CLASS_UNTAGGED,
                               NULL, &heap_callbacks, &data);

            }
        }

        /* Use data error if needed */
        if ( error == JVMTI_ERROR_NONE ) {
            error = data.error;
        }

    }

    /* Dispose of any special jvmti environment */
    (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
    return error;
}

/* ********************************************************************* */
/* Referrers */

/* Structure to hold object referrer heap traversal data (arg user_data) */
typedef struct ReferrerData {
  int        refCount;
  int        maxObjects;
  jlong      refTag;
  jlong      objTag;
  jboolean   selfRef;
  jvmtiError error;
} ReferrerData;

/* Callback for referrers object tagging (heap_reference_callback). */
static jint JNICALL
cbObjectTagReferrer(jvmtiHeapReferenceKind reference_kind,
     const jvmtiHeapReferenceInfo* reference_info, jlong class_tag,
     jlong referrer_class_tag, jlong size,
     jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data)
{
    ReferrerData  *data;

    /* Check data structure */
    data = (ReferrerData*)user_data;
    if (data == NULL) {
        data->error = AGENT_ERROR_ILLEGAL_ARGUMENT;
        return JVMTI_VISIT_ABORT;
    }

    /* If we have tagged enough objects, just abort */
    if ( data->maxObjects != 0 && data->refCount >= data->maxObjects ) {
        return JVMTI_VISIT_ABORT;
    }

    /* If not of interest, just continue */
    if ( (*tag_ptr) != data->objTag ) {
        return JVMTI_VISIT_OBJECTS;
    }

    /* Self reference that we haven't counted? */
    if ( tag_ptr == referrer_tag_ptr ) {
        if ( data->selfRef == JNI_FALSE ) {
            data->selfRef = JNI_TRUE;
            data->refCount++;
        }
        return JVMTI_VISIT_OBJECTS;
    }

    /* If the referrer can be tagged, and hasn't been tagged, tag it */
    if ( referrer_tag_ptr != NULL ) {
        if ( (*referrer_tag_ptr) == (jlong)0 ) {
            *referrer_tag_ptr = data->refTag;
            data->refCount++;
        }
    }
    return JVMTI_VISIT_OBJECTS;
}

/* Heap traversal to find referrers of an object */
jvmtiError
objectReferrers(jobject obj, ObjectBatch *referrers, int maxObjects)
{
    jvmtiHeapCallbacks heap_callbacks;
    ReferrerData       data;
    jvmtiError         error;
    jvmtiEnv          *jvmti;

    /* Check interface assumptions */
    if (obj == NULL) {
        return AGENT_ERROR_INVALID_OBJECT;
    }
    if (referrers == NULL || maxObjects < 0 ) {
        return AGENT_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Initialize return information */
    referrers->count = 0;
    referrers->objects = NULL;

    /* Get jvmti environment to use */
    jvmti = getSpecialJvmti();
    if ( jvmti == NULL ) {
        return AGENT_ERROR_INTERNAL;
    }

    /* Fill in the data structure passed around the callbacks */
    data.refCount   = 0;
    data.maxObjects = maxObjects;
    data.objTag     = (jlong)1;
    data.refTag     = (jlong)2;
    data.selfRef    = JNI_FALSE;
    data.error      = JVMTI_ERROR_NONE;

    /* Tag the object of interest */
    error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.objTag);

    /* No need to go any further if we can't tag the object */
    if ( error == JVMTI_ERROR_NONE ) {

        /* Clear out callbacks structure */
        (void)memset(&heap_callbacks,0,sizeof(heap_callbacks));

        /* Setup callbacks we want */
        heap_callbacks.heap_reference_callback = &cbObjectTagReferrer;

        /* Follow references, no initiating object, all classes, 1 tagged objs */
        error = JVMTI_FUNC_PTR(jvmti,FollowReferences)
                      (jvmti, JVMTI_HEAP_FILTER_UNTAGGED,
                       NULL, NULL, &heap_callbacks, &data);

        /* Use data error if needed */
        if ( error == JVMTI_ERROR_NONE ) {
            error = data.error;
        }

    }

    /* Watch out for self-reference */
    if ( error == JVMTI_ERROR_NONE && data.selfRef == JNI_TRUE ) {
        /* Tag itself as a referer */
        error = JVMTI_FUNC_PTR(jvmti,SetTag) (jvmti, obj, data.refTag);
    }

    /* Get the jobjects for the tagged referrer objects.  */
    if ( error == JVMTI_ERROR_NONE ) {
        error = JVMTI_FUNC_PTR(jvmti,GetObjectsWithTags)
                    (jvmti, 1, &(data.refTag), &(referrers->count),
                          &(referrers->objects), NULL);
        /* Verify we got the count we expected */
        if ( data.refCount != referrers->count ) {
            error = AGENT_ERROR_INTERNAL;
        }
    }

    /* Dispose of any special jvmti environment */
    (void)JVMTI_FUNC_PTR(jvmti,DisposeEnvironment)(jvmti);
    return error;
}
