/*
 * Copyright (c) 1998, 2007, 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.
 */

#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;
}
