/*
 * Copyright (c) 1998, 2006, 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 "util.h"
#include "VirtualMachineImpl.h"
#include "commonRef.h"
#include "inStream.h"
#include "outStream.h"
#include "eventHandler.h"
#include "eventHelper.h"
#include "threadControl.h"
#include "SDE.h"
#include "FrameID.h"

// ANDROID-CHANGED: Need to sent metrics before doExit
#include "timing.h"


static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
static int majorVersion = 1;  /* JDWP major version */
static int minorVersion = 8;  /* JDWP minor version */

static jboolean
version(PacketInputStream *in, PacketOutputStream *out)
{
    char buf[500];
    char *vmName;
    char *vmVersion;
    char *vmInfo;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    vmVersion = gdata->property_java_version;
    if (vmVersion == NULL) {
        vmVersion = "<unknown>";
    }
    // ANDROID-CHANGED: The runtime value of the java.version property has always been "0" on
    //                  android but the old debugger just sent a different value. Simply sending "0"
    //                  can confuse some JDWP clients so we will simply say that we are version "8".
    if (strcmp(gdata->property_java_vm_name, "Dalvik") == 0 && strcmp(vmVersion, "0") == 0) {
      vmVersion = "8";
    }
    vmName = gdata->property_java_vm_name;
    if (vmName == NULL) {
        vmName = "<unknown>";
    }
    vmInfo = gdata->property_java_vm_info;
    if (vmInfo == NULL) {
        vmInfo = "<unknown>";
    }

    /*
     * Write the descriptive version information
     */
    (void)snprintf(buf, sizeof(buf),
                "%s version %d.%d\nJVM Debug Interface version %d.%d\n"
                 "JVM version %s (%s, %s)",
                  versionName, majorVersion, minorVersion,
                  jvmtiMajorVersion(), jvmtiMinorVersion(),
                  vmVersion, vmName, vmInfo);
    (void)outStream_writeString(out, buf);

    /*
     * Write the JDWP version numbers
     */
    (void)outStream_writeInt(out, majorVersion);
    (void)outStream_writeInt(out, minorVersion);

    /*
     * Write the VM version and name
     */
    (void)outStream_writeString(out, vmVersion);
    (void)outStream_writeString(out, vmName);

    return JNI_TRUE;
}

static jboolean
classesForSignature(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    char *signature;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    signature = inStream_readString(in);
    if (signature == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jint classCount;
        jclass *theClasses;
        jvmtiError error;

        error = allLoadedClasses(&theClasses, &classCount);
        if ( error == JVMTI_ERROR_NONE ) {
            /* Count classes in theClasses which match signature */
            int matchCount = 0;
            /* Count classes written to the JDWP connection */
            int writtenCount = 0;
            int i;

            for (i=0; i<classCount; i++) {
                jclass clazz = theClasses[i];
                jint status = classStatus(clazz);
                char *candidate_signature = NULL;
                jint wanted =
                    (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY|
                     JVMTI_CLASS_STATUS_PRIMITIVE);

                /* We want prepared classes, primitives, and arrays only */
                if ((status & wanted) == 0) {
                    continue;
                }

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

                if (strcmp(candidate_signature, signature) == 0) {
                    /* Float interesting classes (those that
                     * are matching and are prepared) to the
                     * beginning of the array.
                     */
                    theClasses[i] = theClasses[matchCount];
                    theClasses[matchCount++] = clazz;
                }
                jvmtiDeallocate(candidate_signature);
            }

            /* At this point matching prepared classes occupy
             * indicies 0 thru matchCount-1 of theClasses.
             */

            if ( error ==  JVMTI_ERROR_NONE ) {
                (void)outStream_writeInt(out, matchCount);
                for (; writtenCount < matchCount; writtenCount++) {
                    jclass clazz = theClasses[writtenCount];
                    jint status = classStatus(clazz);
                    jbyte tag = referenceTypeTag(clazz);
                    (void)outStream_writeByte(out, tag);
                    (void)outStream_writeObjectRef(env, out, clazz);
                    (void)outStream_writeInt(out, map2jdwpClassStatus(status));
                    /* No point in continuing if there's an error */
                    if (outStream_error(out)) {
                        break;
                    }
                }
            }

            jvmtiDeallocate(theClasses);
        }

        if ( error != JVMTI_ERROR_NONE ) {
            outStream_setError(out, map2jdwpError(error));
        }

    } END_WITH_LOCAL_REFS(env);

    jvmtiDeallocate(signature);

    return JNI_TRUE;
}

static jboolean
allClasses1(PacketInputStream *in, PacketOutputStream *out, int outputGenerics)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jint classCount;
        jclass *theClasses;
        jvmtiError error;

        error = allLoadedClasses(&theClasses, &classCount);
        if ( error != JVMTI_ERROR_NONE ) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            /* Count classes in theClasses which are prepared */
            int prepCount = 0;
            /* Count classes written to the JDWP connection */
            int writtenCount = 0;
            int i;

            for (i=0; i<classCount; i++) {
                jclass clazz = theClasses[i];
                jint status = classStatus(clazz);
                jint wanted =
                    (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY);

                /* We want prepared classes and arrays only */
                if ((status & wanted) != 0) {
                    /* Float interesting classes (those that
                     * are prepared) to the beginning of the array.
                     */
                    theClasses[i] = theClasses[prepCount];
                    theClasses[prepCount++] = clazz;
                }
            }

            /* At this point prepared classes occupy
             * indicies 0 thru prepCount-1 of theClasses.
             */

            (void)outStream_writeInt(out, prepCount);
            for (; writtenCount < prepCount; writtenCount++) {
                char *signature = NULL;
                char *genericSignature = NULL;
                jclass clazz = theClasses[writtenCount];
                jint status = classStatus(clazz);
                jbyte tag = referenceTypeTag(clazz);
                jvmtiError error;

                error = classSignature(clazz, &signature, &genericSignature);
                if (error != JVMTI_ERROR_NONE) {
                    outStream_setError(out, map2jdwpError(error));
                    break;
                }

                (void)outStream_writeByte(out, tag);
                (void)outStream_writeObjectRef(env, out, clazz);
                (void)outStream_writeString(out, signature);
                if (outputGenerics == 1) {
                    writeGenericSignature(out, genericSignature);
                }

                (void)outStream_writeInt(out, map2jdwpClassStatus(status));
                jvmtiDeallocate(signature);
                if (genericSignature != NULL) {
                  jvmtiDeallocate(genericSignature);
                }

                /* No point in continuing if there's an error */
                if (outStream_error(out)) {
                    break;
                }
            }
            jvmtiDeallocate(theClasses);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
allClasses(PacketInputStream *in, PacketOutputStream *out)
{
    return allClasses1(in, out, 0);
}

static jboolean
allClassesWithGeneric(PacketInputStream *in, PacketOutputStream *out)
{
    return allClasses1(in, out, 1);
}

  /***********************************************************/


static jboolean
instanceCounts(PacketInputStream *in, PacketOutputStream *out)
{
    jint classCount;
    jclass *classes;
    JNIEnv *env;
    int ii;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    classCount = inStream_readInt(in);

    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    if (classCount == 0) {
        (void)outStream_writeInt(out, 0);
        return JNI_TRUE;
    }
    if (classCount < 0) {
        outStream_setError(out, JDWP_ERROR(ILLEGAL_ARGUMENT));
        return JNI_TRUE;
    }
    env = getEnv();
    classes = jvmtiAllocate(classCount * (int)sizeof(jclass));
    for (ii = 0; ii < classCount; ii++) {
        jdwpError errorCode;
        classes[ii] = inStream_readClassRef(env, in);
        errorCode = inStream_error(in);
        if (errorCode != JDWP_ERROR(NONE)) {
            /*
             * A class could have been unloaded/gc'd so
             * if we get an error, just ignore it and keep
             * going.  An instanceCount of 0 will be returned.
             */
            if (errorCode == JDWP_ERROR(INVALID_OBJECT) ||
                errorCode == JDWP_ERROR(INVALID_CLASS)) {
                inStream_clearError(in);
                classes[ii] = NULL;
                continue;
            }
            jvmtiDeallocate(classes);
            return JNI_TRUE;
        }
    }

    WITH_LOCAL_REFS(env, 1) {
        jlong      *counts;
        jvmtiError error;

        counts = jvmtiAllocate(classCount * (int)sizeof(jlong));
        /* Iterate over heap getting info on these classes */
        error = classInstanceCounts(classCount, classes, counts);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            (void)outStream_writeInt(out, classCount);
            for (ii = 0; ii < classCount; ii++) {
                (void)outStream_writeLong(out, counts[ii]);
            }
        }
        jvmtiDeallocate(counts);
    } END_WITH_LOCAL_REFS(env);
    jvmtiDeallocate(classes);
    return JNI_TRUE;
}

static jboolean
redefineClasses(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiClassDefinition *classDefs;
    jboolean ok = JNI_TRUE;
    jint classCount;
    jint i;
    JNIEnv *env;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    classCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    if ( classCount == 0 ) {
        return JNI_TRUE;
    }
    /*LINTED*/
    classDefs = jvmtiAllocate(classCount*(int)sizeof(jvmtiClassDefinition));
    if (classDefs == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    /*LINTED*/
    (void)memset(classDefs, 0, classCount*sizeof(jvmtiClassDefinition));

    env = getEnv();
    for (i = 0; i < classCount; ++i) {
        int byteCount;
        unsigned char * bytes;
        jclass clazz;

        clazz = inStream_readClassRef(env, in);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }
        byteCount = inStream_readInt(in);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }
        if ( byteCount <= 0 ) {
            outStream_setError(out, JDWP_ERROR(INVALID_CLASS_FORMAT));
            ok = JNI_FALSE;
            break;
        }
        bytes = (unsigned char *)jvmtiAllocate(byteCount);
        if (bytes == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
            ok = JNI_FALSE;
            break;
        }
        (void)inStream_readBytes(in, byteCount, (jbyte *)bytes);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }

        classDefs[i].klass = clazz;
        classDefs[i].class_byte_count = byteCount;
        classDefs[i].class_bytes = bytes;
    }

    if (ok == JNI_TRUE) {
        jvmtiError error;

        error = JVMTI_FUNC_PTR(gdata->jvmti,RedefineClasses)
                        (gdata->jvmti, classCount, classDefs);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            /* zap our BP info */
            for ( i = 0 ; i < classCount; i++ ) {
                eventHandler_freeClassBreakpoints(classDefs[i].klass);
            }
        }
    }

    /* free up allocated memory */
    for ( i = 0 ; i < classCount; i++ ) {
        if ( classDefs[i].class_bytes != NULL ) {
            jvmtiDeallocate((void*)classDefs[i].class_bytes);
        }
    }
    jvmtiDeallocate(classDefs);

    return JNI_TRUE;
}

static jboolean
setDefaultStratum(PacketInputStream *in, PacketOutputStream *out)
{
    char *stratumId;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    stratumId = inStream_readString(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    } else if (strcmp(stratumId, "") == 0) {
        stratumId = NULL;
    }
    setGlobalStratumId(stratumId);

    return JNI_TRUE;
}

static jboolean
getAllThreads(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        int i;
        jint threadCount;
        jthread *theThreads;

        theThreads = allThreads(&threadCount);
        if (theThreads == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        } else {
            /* Squish out all of the debugger-spawned threads */
            threadCount = filterDebugThreads(theThreads, threadCount);

            (void)outStream_writeInt(out, threadCount);
            for (i = 0; i <threadCount; i++) {
                (void)outStream_writeObjectRef(env, out, theThreads[i]);
            }

            jvmtiDeallocate(theThreads);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
topLevelThreadGroups(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error;
        jint groupCount;
        jthreadGroup *groups;

        groups = NULL;
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
                    (gdata->jvmti, &groupCount, &groups);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;

            (void)outStream_writeInt(out, groupCount);
            for (i = 0; i < groupCount; i++) {
                (void)outStream_writeObjectRef(env, out, groups[i]);
            }

            jvmtiDeallocate(groups);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
dispose(PacketInputStream *in, PacketOutputStream *out)
{
    return JNI_TRUE;
}

static jboolean
idSizes(PacketInputStream *in, PacketOutputStream *out)
{
    (void)outStream_writeInt(out, sizeof(jfieldID));    /* fields */
    (void)outStream_writeInt(out, sizeof(jmethodID));   /* methods */
    (void)outStream_writeInt(out, sizeof(jlong));       /* objects */
    (void)outStream_writeInt(out, sizeof(jlong));       /* referent types */
    (void)outStream_writeInt(out, sizeof(FrameID));    /* frames */
    return JNI_TRUE;
}

static jboolean
suspend(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = threadControl_suspendAll();
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
resume(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = threadControl_resumeAll();
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
doExit(PacketInputStream *in, PacketOutputStream *out)
{
    // ANDROID-CHANGED: We are about to exit(). Send ART cmd processing time,
    // if there are any remaining.
    timings_flush();

    jint exitCode;

    exitCode = inStream_readInt(in);
    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_FALSE;
    }

    /* We send the reply from here because we are about to exit. */
    if (inStream_error(in)) {
        outStream_setError(out, inStream_error(in));
    }
    outStream_sendReply(out);

    forceExit(exitCode);

    /* Shouldn't get here */
    JDI_ASSERT(JNI_FALSE);

    /* Shut up the compiler */
    return JNI_FALSE;

}

static jboolean
createString(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    char *cstring;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    cstring = inStream_readString(in);
    if (cstring == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jstring string;

        string = JNI_FUNC_PTR(env,NewStringUTF)(env, cstring);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        } else {
            (void)outStream_writeObjectRef(env, out, string);
        }

    } END_WITH_LOCAL_REFS(env);

    jvmtiDeallocate(cstring);

    return JNI_TRUE;
}

static jboolean
capabilities(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiCapabilities caps;
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = jvmtiGetCapabilities(&caps);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);
    return JNI_TRUE;
}

static jboolean
capabilitiesNew(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiCapabilities caps;
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = jvmtiGetCapabilities(&caps);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    // ANDROID-CHANGED: We want to adjust the capabilities slightly if we are on android.
    jboolean is_android_runtime = strcmp(gdata->property_java_vm_name, "Dalvik") == 0;

    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);

    /* new since JDWP version 1.4 */
    /* ANDROID-CHANGED: some jdwp clients will send us class files for redefineClasses which we do
     * not support. Set this capability to false and set reserved32 instead to indicate that we do
     * support .dex file class redefinition.
     */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_redefine_classes && !is_android_runtime);
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_add_method */ );
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_unrestrictedly_redefine_classes */ );
    /* 11: canPopFrames */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_pop_frame);
    /* 12: canUseInstanceFilters */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 13: canGetSourceDebugExtension */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_source_debug_extension);
    /* 14: canRequestVMDeathEvent */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 15: canSetDefaultStratum */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 16: canGetInstanceInfo */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_tag_objects);
    /* 17: canRequestMonitorEvents */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_monitor_events);
    /* 18: canGetMonitorFrameInfo */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_stack_depth_info);
    /* remaining reserved */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 19 */
    /* 20 Can get constant pool information */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_constant_pool);
    /* 21 Can force early return */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_force_early_return);
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 22 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 23 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 24 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 25 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 26 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 27 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 28 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 29 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 30 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 31 */
    /* ANDROID-CHANGED: Use the reserved32 capability to notify clients that we can support dex
     * class redefinition.
     */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_redefine_classes && is_android_runtime);
    return JNI_TRUE;
}

static int
countPaths(char *string) {
    int cnt = 1; /* always have one */
    char *pos = string;
    char *ps;

    ps = gdata->property_path_separator;
    if ( ps == NULL ) {
        ps = ";";
    }
    while ((pos = strchr(pos, ps[0])) != NULL) {
        ++cnt;
        ++pos;
    }
    return cnt;
}

static void
writePaths(PacketOutputStream *out, char *string) {
    char *pos;
    char *ps;
    char *buf;
    int   npaths;
    int   i;

    buf = jvmtiAllocate((int)strlen(string)+1);

    npaths = countPaths(string);
    (void)outStream_writeInt(out, npaths);

    ps = gdata->property_path_separator;
    if ( ps == NULL ) {
        ps = ";";
    }

    pos = string;
    for ( i = 0 ; i < npaths ; i++ ) {
        char *psPos;
        int   plen;

        psPos = strchr(pos, ps[0]);
        if ( psPos == NULL ) {
            plen = (int)strlen(pos);
        } else {
            plen = (int)(psPos-pos);
            psPos++;
        }
        (void)memcpy(buf, pos, plen);
        buf[plen] = 0;
        (void)outStream_writeString(out, buf);
        pos = psPos;
    }

    jvmtiDeallocate(buf);
}



static jboolean
classPaths(PacketInputStream *in, PacketOutputStream *out)
{
    char *ud;
    char *bp;
    char *cp;

    ud = gdata->property_user_dir;
    if ( ud == NULL ) {
        ud = "";
    }
    cp = gdata->property_java_class_path;
    if ( cp == NULL ) {
        cp = "";
    }
    bp = gdata->property_sun_boot_class_path;
    if ( bp == NULL ) {
        bp = "";
    }
    (void)outStream_writeString(out, ud);
    writePaths(out, cp);
    writePaths(out, bp);
    return JNI_TRUE;
}

static jboolean
disposeObjects(PacketInputStream *in, PacketOutputStream *out)
{
    int i;
    int refCount;
    jlong id;
    int requestCount;
    JNIEnv *env;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    requestCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();
    for (i = 0; i < requestCount; i++) {
        id = inStream_readObjectID(in);
        refCount = inStream_readInt(in);
        if (inStream_error(in)) {
            return JNI_TRUE;
        }
        commonRef_releaseMultiple(env, id, refCount);
    }

    return JNI_TRUE;
}

static jboolean
holdEvents(PacketInputStream *in, PacketOutputStream *out)
{
    eventHelper_holdEvents();
    return JNI_TRUE;
}

static jboolean
releaseEvents(PacketInputStream *in, PacketOutputStream *out)
{
    eventHelper_releaseEvents();
    return JNI_TRUE;
}

void *VirtualMachine_Cmds[] = { (void *)21
    ,(void *)version
    ,(void *)classesForSignature
    ,(void *)allClasses
    ,(void *)getAllThreads
    ,(void *)topLevelThreadGroups
    ,(void *)dispose
    ,(void *)idSizes
    ,(void *)suspend
    ,(void *)resume
    ,(void *)doExit
    ,(void *)createString
    ,(void *)capabilities
    ,(void *)classPaths
    ,(void *)disposeObjects
    ,(void *)holdEvents
    ,(void *)releaseEvents
    ,(void *)capabilitiesNew
    ,(void *)redefineClasses
    ,(void *)setDefaultStratum
    ,(void *)allClassesWithGeneric
    ,(void *)instanceCounts
};
