Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  */
     18 
     19 /**
     20  * @author Vitaly A. Provodin
     21  */
     22 
     23 package org.apache.harmony.jpda.tests.framework.jdwp;
     24 
     25 import java.io.IOException;
     26 import java.util.ArrayList;
     27 import java.util.Iterator;
     28 import java.util.List;
     29 
     30 import org.apache.harmony.jpda.tests.framework.Breakpoint;
     31 import org.apache.harmony.jpda.tests.framework.LogWriter;
     32 import org.apache.harmony.jpda.tests.framework.TestErrorException;
     33 import org.apache.harmony.jpda.tests.framework.TestOptions;
     34 import org.apache.harmony.jpda.tests.framework.jdwp.Capabilities;
     35 import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
     36 import org.apache.harmony.jpda.tests.framework.jdwp.Event;
     37 import org.apache.harmony.jpda.tests.framework.jdwp.EventMod;
     38 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
     39 import org.apache.harmony.jpda.tests.framework.jdwp.Location;
     40 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
     41 import org.apache.harmony.jpda.tests.framework.jdwp.TransportWrapper;
     42 import org.apache.harmony.jpda.tests.framework.jdwp.TypesLengths;
     43 import org.apache.harmony.jpda.tests.framework.jdwp.Frame.Variable;
     44 import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.ReplyErrorCodeException;
     45 import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.TimeoutException;
     46 
     47 /**
     48  * This class provides convenient way for communicating with debuggee VM using
     49  * JDWP packets.
     50  * <p>
     51  * Most methods can throw ReplyErrorCodeException if error occurred in execution
     52  * of corresponding JDWP command or TestErrorException if any other error
     53  * occurred.
     54  */
     55 public class VmMirror {
     56 
     57     /** Target VM Capabilities. */
     58     private Capabilities targetVMCapabilities;
     59 
     60     /** Transport used to sent and receive packets. */
     61     private TransportWrapper connection;
     62 
     63     /** PacketDispatcher thread used for asynchronous reading packets. */
     64     private PacketDispatcher packetDispatcher;
     65 
     66     /** Test run options. */
     67     protected TestOptions config;
     68 
     69     /** Log to write messages. */
     70     protected LogWriter logWriter;
     71 
     72     /**
     73      * Creates new VmMirror instance for given test run options.
     74      *
     75      * @param config
     76      *            test run options
     77      * @param logWriter
     78      *            log writer
     79      */
     80     public VmMirror(TestOptions config, LogWriter logWriter) {
     81         connection = null;
     82         this.config = config;
     83         this.logWriter = logWriter;
     84     }
     85 
     86     /**
     87      * Checks error code of given reply packet and throws
     88      * ReplyErrorCodeException if any error detected.
     89      *
     90      * @param reply
     91      *            reply packet to check
     92      * @return ReplyPacket unchanged reply packet
     93      */
     94     public ReplyPacket checkReply(ReplyPacket reply) {
     95         if (reply.getErrorCode() != JDWPConstants.Error.NONE)
     96             throw new ReplyErrorCodeException(reply.getErrorCode());
     97         return reply;
     98     }
     99 
    100     /**
    101      * Sets breakpoint to given location.
    102      *
    103      * @param typeTag
    104      * @param breakpoint
    105      * @return ReplyPacket for corresponding command
    106      */
    107     public ReplyPacket setBreakpoint(byte typeTag, Breakpoint breakpoint) {
    108 
    109         return setBreakpoint(typeTag, breakpoint,
    110                 JDWPConstants.SuspendPolicy.ALL);
    111     }
    112 
    113     /**
    114      * Sets breakpoint to given location.
    115      *
    116      * @param typeTag
    117      * @param breakpoint
    118      * @param suspendPolicy
    119      *            Suspend policy for a breakpoint being created
    120      * @return ReplyPacket for corresponding command
    121      */
    122     public ReplyPacket setBreakpoint(byte typeTag, Breakpoint breakpoint,
    123             byte suspendPolicy) {
    124         // Get Class reference ID
    125         long typeID = getTypeID(breakpoint.className, typeTag);
    126 
    127         // Get Method reference ID
    128         long methodID = getMethodID(typeID, breakpoint.methodName);
    129 
    130         // Fill location
    131         Location location = new Location(typeTag, typeID, methodID,
    132                 breakpoint.index);
    133 
    134         // Set breakpoint
    135         return setBreakpoint(location, suspendPolicy);
    136     }
    137 
    138     /**
    139      * Sets breakpoint to given location.
    140      *
    141      * @param location
    142      *            Location of breakpoint
    143      * @return ReplyPacket for corresponding command
    144      */
    145     public ReplyPacket setBreakpoint(Location location) {
    146 
    147         return setBreakpoint(location, JDWPConstants.SuspendPolicy.ALL);
    148     }
    149 
    150     /**
    151      * Sets breakpoint to given location
    152      *
    153      * @param location
    154      *            Location of breakpoint
    155      * @param suspendPolicy
    156      *            Suspend policy for a breakpoint being created
    157      * @return ReplyPacket for corresponding command
    158      */
    159     public ReplyPacket setBreakpoint(Location location, byte suspendPolicy) {
    160         // Prepare corresponding event
    161         byte eventKind = JDWPConstants.EventKind.BREAKPOINT;
    162 
    163         // EventMod[] mods = new EventMod[1];
    164         EventMod[] mods = new EventMod[] { new EventMod() };
    165 
    166         mods[0].loc = location;
    167         mods[0].modKind = EventMod.ModKind.LocationOnly;
    168         Event event = new Event(eventKind, suspendPolicy, mods);
    169 
    170         // Set breakpoint
    171         return setEvent(event);
    172     }
    173 
    174     /**
    175      * Sets breakpoint that triggers only on a certain occurrence to a given
    176      * location
    177      *
    178      * @param typeTag
    179      * @param breakpoint
    180      * @param suspendPolicy
    181      *            Suspend policy for a breakpoint being created
    182      * @param count
    183      *            Limit the requested event to be reported at most once after a
    184      *            given number of occurrences
    185      * @return ReplyPacket for corresponding command
    186      */
    187     public ReplyPacket setCountableBreakpoint(byte typeTag,
    188             Breakpoint breakpoint, byte suspendPolicy, int count) {
    189         long typeID = getTypeID(breakpoint.className, typeTag);
    190 
    191         // Get Method reference ID
    192         long methodID = getMethodID(typeID, breakpoint.methodName);
    193 
    194         byte eventKind = JDWPConstants.EventKind.BREAKPOINT;
    195 
    196         EventMod mod1 = new EventMod();
    197         mod1.modKind = EventMod.ModKind.LocationOnly;
    198         mod1.loc = new Location(typeTag, typeID, methodID, breakpoint.index);
    199 
    200         EventMod mod2 = new EventMod();
    201         mod2.modKind = EventMod.ModKind.Count;
    202         mod2.count = count;
    203 
    204         EventMod[] mods = new EventMod[] { mod1, mod2 };
    205         Event event = new Event(eventKind, suspendPolicy, mods);
    206 
    207         // Set breakpoint
    208         return setEvent(event);
    209     }
    210 
    211     /**
    212      * Sets breakpoint at the beginning of method with name <i>methodName</i>.
    213      *
    214      * @param classID
    215      *            id of class with required method
    216      * @param methodName
    217      *            name of required method
    218      * @return requestID id of request
    219      */
    220     public int setBreakpointAtMethodBegin(long classID, String methodName) {
    221         return setBreakpointAtMethodBegin(classID, methodName, JDWPConstants.SuspendPolicy.ALL);
    222     }
    223 
    224     /**
    225      * Sets breakpoint at the beginning of method with name <i>methodName</i>.
    226      *
    227      * @param classID
    228      *            id of class with required method
    229      * @param methodName
    230      *            name of required method
    231      * @return requestID id of request
    232      */
    233     public int setBreakpointAtMethodBegin(long classID, String methodName, byte suspendPolicy) {
    234         long methodID = getMethodID(classID, methodName);
    235 
    236         ReplyPacket lineTableReply = getLineTable(classID, methodID);
    237         if (lineTableReply.getErrorCode() != JDWPConstants.Error.NONE) {
    238             throw new TestErrorException(
    239                     "Command getLineTable returned error code: "
    240                             + lineTableReply.getErrorCode()
    241                             + " - "
    242                             + JDWPConstants.Error.getName(lineTableReply
    243                                     .getErrorCode()));
    244         }
    245 
    246         lineTableReply.getNextValueAsLong();
    247         // Lowest valid code index for the method
    248 
    249         lineTableReply.getNextValueAsLong();
    250         // Highest valid code index for the method
    251 
    252         // int numberOfLines =
    253         lineTableReply.getNextValueAsInt();
    254 
    255         long lineCodeIndex = lineTableReply.getNextValueAsLong();
    256 
    257         // set breakpoint inside checked method
    258         Location breakpointLocation = new Location(JDWPConstants.TypeTag.CLASS,
    259                 classID, methodID, lineCodeIndex);
    260 
    261         ReplyPacket reply = setBreakpoint(breakpointLocation, suspendPolicy);
    262         checkReply(reply);
    263 
    264         return reply.getNextValueAsInt();
    265     }
    266 
    267     /**
    268      * Waits for stop on breakpoint and gets id of thread where it stopped.
    269      *
    270      * @param requestID
    271      *            id of request for breakpoint
    272      * @return threadID id of thread, where we stop on breakpoint
    273      */
    274     public long waitForBreakpoint(int requestID) {
    275         // receive event
    276         CommandPacket event = null;
    277         event = receiveEvent();
    278 
    279         event.getNextValueAsByte();
    280         // suspendPolicy - is not used here
    281 
    282         // int numberOfEvents =
    283         event.getNextValueAsInt();
    284 
    285         long breakpointThreadID = 0;
    286         ParsedEvent[] eventParsed = ParsedEvent.parseEventPacket(event);
    287 
    288         if (eventParsed.length != 1) {
    289             throw new TestErrorException("Received " + eventParsed.length
    290                     + " events instead of 1 BREAKPOINT_EVENT");
    291         }
    292 
    293         // check if received event is for breakpoint
    294         if (eventParsed[0].getEventKind() == JDWPConstants.EventKind.BREAKPOINT) {
    295             breakpointThreadID = ((ParsedEvent.Event_BREAKPOINT) eventParsed[0])
    296                     .getThreadID();
    297 
    298         } else {
    299             throw new TestErrorException(
    300                     "Kind of received event is not BREAKPOINT_EVENT: "
    301                             + eventParsed[0].getEventKind());
    302 
    303         }
    304 
    305         if (eventParsed[0].getRequestID() != requestID) {
    306             throw new TestErrorException(
    307                     "Received BREAKPOINT_EVENT with another requestID: "
    308                             + eventParsed[0].getRequestID());
    309         }
    310 
    311         return breakpointThreadID;
    312     }
    313 
    314     /**
    315      * Removes breakpoint according to specified requestID.
    316      *
    317      * @param requestID
    318      *            for given breakpoint
    319      * @return ReplyPacket for corresponding command
    320      */
    321     public ReplyPacket clearBreakpoint(int requestID) {
    322 
    323         // Create new command packet
    324         CommandPacket commandPacket = new CommandPacket();
    325 
    326         // Set command. "2" - is ID of Clear command in EventRequest Command Set
    327         commandPacket
    328                 .setCommand(JDWPCommands.EventRequestCommandSet.ClearCommand);
    329 
    330         // Set command set. "15" - is ID of EventRequest Command Set
    331         commandPacket
    332                 .setCommandSet(JDWPCommands.EventRequestCommandSet.CommandSetID);
    333 
    334         // Set outgoing data
    335         // Set eventKind
    336         commandPacket.setNextValueAsByte(JDWPConstants.EventKind.BREAKPOINT);
    337 
    338         // Set suspendPolicy
    339         commandPacket.setNextValueAsInt(requestID);
    340 
    341         // Send packet
    342         return checkReply(performCommand(commandPacket));
    343     }
    344 
    345     /**
    346      * Removes all breakpoints.
    347      *
    348      * @return ReplyPacket for corresponding command
    349      */
    350     public ReplyPacket ClearAllBreakpoints() {
    351 
    352         // Create new command packet
    353         CommandPacket commandPacket = new CommandPacket();
    354 
    355         // Set command. "3" - is ID of ClearAllBreakpoints command in
    356         // EventRequest Command Set
    357         commandPacket
    358                 .setCommand(JDWPCommands.EventRequestCommandSet.ClearAllBreakpointsCommand);
    359 
    360         // Set command set. "15" - is ID of EventRequest Command Set
    361         commandPacket
    362                 .setCommandSet(JDWPCommands.EventRequestCommandSet.CommandSetID);
    363 
    364         // Send packet
    365         return checkReply(performCommand(commandPacket));
    366     }
    367 
    368     /**
    369      * Requests debuggee VM capabilities. Function parses reply packet of
    370      * VirtualMachine::CapabilitiesNew command, creates and fills class
    371      * Capabilities with returned info.
    372      *
    373      * @return ReplyPacket useless, already parsed reply packet.
    374      */
    375     public ReplyPacket capabilities() {
    376 
    377         // Create new command packet
    378         CommandPacket commandPacket = new CommandPacket();
    379 
    380         // Set command. "17" - is ID of CapabilitiesNew command in
    381         // VirtualMachine Command Set
    382         commandPacket
    383                 .setCommand(JDWPCommands.VirtualMachineCommandSet.CapabilitiesNewCommand);
    384 
    385         // Set command set. "1" - is ID of VirtualMachine Command Set
    386         commandPacket
    387                 .setCommandSet(JDWPCommands.VirtualMachineCommandSet.CommandSetID);
    388 
    389         // Send packet
    390         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    391 
    392         targetVMCapabilities = new Capabilities();
    393 
    394         // Set capabilities
    395         targetVMCapabilities.canWatchFieldModification = replyPacket
    396                 .getNextValueAsBoolean();
    397         targetVMCapabilities.canWatchFieldAccess = replyPacket
    398                 .getNextValueAsBoolean();
    399         targetVMCapabilities.canGetBytecodes = replyPacket
    400                 .getNextValueAsBoolean();
    401         targetVMCapabilities.canGetSyntheticAttribute = replyPacket
    402                 .getNextValueAsBoolean();
    403         targetVMCapabilities.canGetOwnedMonitorInfo = replyPacket
    404                 .getNextValueAsBoolean();
    405         targetVMCapabilities.canGetCurrentContendedMonitor = replyPacket
    406                 .getNextValueAsBoolean();
    407         targetVMCapabilities.canGetMonitorInfo = replyPacket
    408                 .getNextValueAsBoolean();
    409         targetVMCapabilities.canRedefineClasses = replyPacket
    410                 .getNextValueAsBoolean();
    411         targetVMCapabilities.canAddMethod = replyPacket.getNextValueAsBoolean();
    412         targetVMCapabilities.canUnrestrictedlyRedefineClasses = replyPacket
    413                 .getNextValueAsBoolean();
    414         targetVMCapabilities.canPopFrames = replyPacket.getNextValueAsBoolean();
    415         targetVMCapabilities.canUseInstanceFilters = replyPacket
    416                 .getNextValueAsBoolean();
    417         targetVMCapabilities.canGetSourceDebugExtension = replyPacket
    418                 .getNextValueAsBoolean();
    419         targetVMCapabilities.canRequestVMDeathEvent = replyPacket
    420                 .getNextValueAsBoolean();
    421         targetVMCapabilities.canSetDefaultStratum = replyPacket
    422                 .getNextValueAsBoolean();
    423         targetVMCapabilities.canGetInstanceInfo = replyPacket
    424                 .getNextValueAsBoolean();
    425         targetVMCapabilities.reserved17 = replyPacket.getNextValueAsBoolean();
    426         targetVMCapabilities.canGetMonitorFrameInfo = replyPacket
    427                 .getNextValueAsBoolean();
    428         targetVMCapabilities.canUseSourceNameFilters = replyPacket.getNextValueAsBoolean();
    429         targetVMCapabilities.canGetConstantPool = replyPacket
    430                 .getNextValueAsBoolean();
    431         targetVMCapabilities.canForceEarlyReturn = replyPacket
    432                 .getNextValueAsBoolean();
    433         targetVMCapabilities.reserved22 = replyPacket.getNextValueAsBoolean();
    434         targetVMCapabilities.reserved23 = replyPacket.getNextValueAsBoolean();
    435         targetVMCapabilities.reserved24 = replyPacket.getNextValueAsBoolean();
    436         targetVMCapabilities.reserved25 = replyPacket.getNextValueAsBoolean();
    437         targetVMCapabilities.reserved26 = replyPacket.getNextValueAsBoolean();
    438         targetVMCapabilities.reserved27 = replyPacket.getNextValueAsBoolean();
    439         targetVMCapabilities.reserved28 = replyPacket.getNextValueAsBoolean();
    440         targetVMCapabilities.reserved29 = replyPacket.getNextValueAsBoolean();
    441         targetVMCapabilities.reserved30 = replyPacket.getNextValueAsBoolean();
    442         targetVMCapabilities.reserved31 = replyPacket.getNextValueAsBoolean();
    443         targetVMCapabilities.reserved32 = replyPacket.getNextValueAsBoolean();
    444 
    445         return replyPacket;
    446     }
    447 
    448     /**
    449      * Indicates whether the capability <i>canRedefineClasses</i> is supported.
    450      *
    451      * @return true if supported, false otherwise.
    452      */
    453     public boolean canRedefineClasses() {
    454         capabilities();
    455         return targetVMCapabilities.canRedefineClasses;
    456     }
    457 
    458     /**
    459      * Indicates whether the capability <i>canPopFrames</i> is supported.
    460      *
    461      * @return true if supported, false otherwise.
    462      */
    463     public boolean canPopFrames() {
    464         capabilities();
    465         return targetVMCapabilities.canPopFrames;
    466     }
    467 
    468     /**
    469      * Indicates whether the capability <i>canGetSourceDebugExtension</i> is supported.
    470      *
    471      * @return true if supported, false otherwise.
    472      */
    473     public boolean canGetSourceDebugExtension() {
    474         capabilities();
    475         return targetVMCapabilities.canGetSourceDebugExtension;
    476     }
    477 
    478     /**
    479      * Indicates whether the capability <i>canRequestVMDeathEvent</i> is supported.
    480      *
    481      * @return true if supported, false otherwise.
    482      */
    483     public boolean canRequestVMDeathEvent() {
    484         capabilities();
    485         return targetVMCapabilities.canRequestVMDeathEvent;
    486     }
    487 
    488     /**
    489      * Indicates whether the capability <i>canSetDefaultStratum</i> is supported.
    490      *
    491      * @return true if supported, false otherwise.
    492      */
    493     public boolean canSetDefaultStratum() {
    494         capabilities();
    495         return targetVMCapabilities.canSetDefaultStratum;
    496     }
    497 
    498     /**
    499      * Indicates whether the capability <i>canUseSourceNameFilters</i> is supported.
    500      *
    501      * @return true if supported, false otherwise.
    502      */
    503     public boolean canUseSourceNameFilters() {
    504         capabilities();
    505         return targetVMCapabilities.canUseSourceNameFilters;
    506     }
    507 
    508     /**
    509      * Indicates whether the capability <i>canGetConstantPool</i> is supported.
    510      *
    511      * @return true if supported, false otherwise.
    512      */
    513     public boolean canGetConstantPool() {
    514         capabilities();
    515         return targetVMCapabilities.canGetConstantPool;
    516     }
    517 
    518     /**
    519      * Indicates whether the capability <i>canForceEarlyReturn</i> is supported.
    520      *
    521      * @return true if supported, false otherwise.
    522      */
    523     public boolean canForceEarlyReturn() {
    524         capabilities();
    525         return targetVMCapabilities.canForceEarlyReturn;
    526     }
    527 
    528     /**
    529      * Resumes debuggee VM.
    530      *
    531      * @return ReplyPacket for corresponding command
    532      */
    533     public ReplyPacket resume() {
    534         CommandPacket commandPacket = new CommandPacket(
    535                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    536                 JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
    537 
    538         return checkReply(performCommand(commandPacket));
    539     }
    540 
    541     /**
    542      * Resumes specified thread on target Virtual Machine
    543      *
    544      * @return ReplyPacket for corresponding command
    545      */
    546     public ReplyPacket resumeThread(long threadID) {
    547         CommandPacket commandPacket = new CommandPacket(
    548                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
    549                 JDWPCommands.ThreadReferenceCommandSet.ResumeCommand);
    550 
    551         commandPacket.setNextValueAsThreadID(threadID);
    552         return checkReply(performCommand(commandPacket));
    553     }
    554 
    555     /**
    556      * Suspends debuggee VM.
    557      *
    558      * @return ReplyPacket for corresponding command
    559      */
    560     public ReplyPacket suspend() {
    561         CommandPacket commandPacket = new CommandPacket(
    562                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    563                 JDWPCommands.VirtualMachineCommandSet.SuspendCommand);
    564 
    565         return checkReply(performCommand(commandPacket));
    566     }
    567 
    568     /**
    569      * Suspends specified thread in debuggee VM.
    570      *
    571      * @return ReplyPacket for corresponding command
    572      */
    573     public ReplyPacket suspendThread(long threadID) {
    574         CommandPacket commandPacket = new CommandPacket(
    575                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
    576                 JDWPCommands.ThreadReferenceCommandSet.SuspendCommand);
    577 
    578         commandPacket.setNextValueAsThreadID(threadID);
    579         return checkReply(performCommand(commandPacket));
    580     }
    581 
    582     /**
    583      * Disposes connection to debuggee VM.
    584      *
    585      * @return ReplyPacket for corresponding command
    586      */
    587     public ReplyPacket dispose() {
    588         // Create new command packet
    589         CommandPacket commandPacket = new CommandPacket();
    590         commandPacket
    591                 .setCommand(JDWPCommands.VirtualMachineCommandSet.DisposeCommand);
    592         commandPacket
    593                 .setCommandSet(JDWPCommands.VirtualMachineCommandSet.CommandSetID);
    594 
    595         // Send packet
    596         return checkReply(performCommand(commandPacket));
    597     }
    598 
    599     /**
    600      * Exits debuggee VM process.
    601      *
    602      * @return ReplyPacket for corresponding command
    603      */
    604     public ReplyPacket exit(int exitCode) {
    605         // Create new command packet
    606         CommandPacket commandPacket = new CommandPacket();
    607         commandPacket
    608                 .setCommand(JDWPCommands.VirtualMachineCommandSet.ExitCommand);
    609         commandPacket
    610                 .setCommandSet(JDWPCommands.VirtualMachineCommandSet.CommandSetID);
    611         commandPacket.setNextValueAsInt(exitCode);
    612 
    613         // Send packet
    614         return checkReply(performCommand(commandPacket));
    615     }
    616 
    617     /**
    618      * Adjusts lengths for all VM-specific types.
    619      *
    620      * @return ReplyPacket for corresponding command
    621      */
    622     public ReplyPacket adjustTypeLength() {
    623         // Create new command packet
    624         CommandPacket commandPacket = new CommandPacket();
    625         commandPacket
    626                 .setCommand(JDWPCommands.VirtualMachineCommandSet.IDSizesCommand);
    627         commandPacket
    628                 .setCommandSet(JDWPCommands.VirtualMachineCommandSet.CommandSetID);
    629 
    630         // Send packet
    631         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    632 
    633         // Get FieldIDSize from ReplyPacket
    634         TypesLengths.setTypeLength(TypesLengths.FIELD_ID, replyPacket
    635                 .getNextValueAsInt());
    636 
    637         // Get MethodIDSize from ReplyPacket
    638         TypesLengths.setTypeLength(TypesLengths.METHOD_ID, replyPacket
    639                 .getNextValueAsInt());
    640 
    641         // Get ObjectIDSize from ReplyPacket
    642         TypesLengths.setTypeLength(TypesLengths.OBJECT_ID, replyPacket
    643                 .getNextValueAsInt());
    644 
    645         // Get ReferenceTypeIDSize from ReplyPacket
    646         TypesLengths.setTypeLength(TypesLengths.REFERENCE_TYPE_ID, replyPacket
    647                 .getNextValueAsInt());
    648 
    649         // Get FrameIDSize from ReplyPacket
    650         TypesLengths.setTypeLength(TypesLengths.FRAME_ID, replyPacket
    651                 .getNextValueAsInt());
    652 
    653         // Adjust all other types lengths
    654         TypesLengths.setTypeLength(TypesLengths.ARRAY_ID, TypesLengths
    655                 .getTypeLength(TypesLengths.OBJECT_ID));
    656         TypesLengths.setTypeLength(TypesLengths.STRING_ID, TypesLengths
    657                 .getTypeLength(TypesLengths.OBJECT_ID));
    658         TypesLengths.setTypeLength(TypesLengths.THREAD_ID, TypesLengths
    659                 .getTypeLength(TypesLengths.OBJECT_ID));
    660         TypesLengths.setTypeLength(TypesLengths.THREADGROUP_ID, TypesLengths
    661                 .getTypeLength(TypesLengths.OBJECT_ID));
    662         TypesLengths.setTypeLength(TypesLengths.LOCATION_ID, TypesLengths
    663                 .getTypeLength(TypesLengths.OBJECT_ID));
    664         TypesLengths.setTypeLength(TypesLengths.CLASS_ID, TypesLengths
    665                 .getTypeLength(TypesLengths.OBJECT_ID));
    666         TypesLengths.setTypeLength(TypesLengths.CLASSLOADER_ID, TypesLengths
    667                 .getTypeLength(TypesLengths.OBJECT_ID));
    668         TypesLengths.setTypeLength(TypesLengths.CLASSOBJECT_ID, TypesLengths
    669                 .getTypeLength(TypesLengths.OBJECT_ID));
    670         return replyPacket;
    671     }
    672 
    673     /**
    674      * Gets TypeID for specified type signature and type tag.
    675      *
    676      * @param typeSignature
    677      *            type signature
    678      * @param classTypeTag
    679      *            type tag
    680      * @return received TypeID
    681      */
    682     public long getTypeID(String typeSignature, byte classTypeTag) {
    683         int classes = 0;
    684         byte refTypeTag = 0;
    685         long typeID = -1;
    686 
    687         // Request referenceTypeID for exception
    688         ReplyPacket classReference = getClassBySignature(typeSignature);
    689 
    690         // Get referenceTypeID from received packet
    691         classes = classReference.getNextValueAsInt();
    692         for (int i = 0; i < classes; i++) {
    693             refTypeTag = classReference.getNextValueAsByte();
    694             if (refTypeTag == classTypeTag) {
    695                 typeID = classReference.getNextValueAsReferenceTypeID();
    696                 classReference.getNextValueAsInt();
    697                 break;
    698             } else {
    699                 classReference.getNextValueAsReferenceTypeID();
    700                 classReference.getNextValueAsInt();
    701                 refTypeTag = 0;
    702             }
    703         }
    704         return typeID;
    705     }
    706 
    707     /**
    708      * Gets ClassID for specified class signature.
    709      *
    710      * @param classSignature
    711      *            class signature
    712      * @return received ClassID
    713      */
    714     public long getClassID(String classSignature) {
    715         return getTypeID(classSignature, JDWPConstants.TypeTag.CLASS);
    716     }
    717 
    718     /**
    719      * Gets ThreadID for specified thread name.
    720      *
    721      * @param threadName
    722      *            thread name
    723      * @return received ThreadID
    724      */
    725     public long getThreadID(String threadName) {
    726         ReplyPacket request = null;
    727         long threadID = -1;
    728         long thread = -1;
    729         String name = null;
    730         int threads = -1;
    731 
    732         // Get All Threads IDs
    733         request = getAllThreadID();
    734 
    735         // Get thread ID for threadName
    736         threads = request.getNextValueAsInt();
    737         for (int i = 0; i < threads; i++) {
    738             thread = request.getNextValueAsThreadID();
    739             name = getThreadName(thread);
    740             if (threadName.equals(name)) {
    741                 threadID = thread;
    742                 break;
    743             }
    744         }
    745 
    746         return threadID;
    747     }
    748 
    749     /**
    750      * Returns all running thread IDs.
    751      *
    752      * @return received reply packet
    753      */
    754     public ReplyPacket getAllThreadID() {
    755         // Create new command packet
    756         CommandPacket commandPacket = new CommandPacket(
    757                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
    758                 JDWPCommands.VirtualMachineCommandSet.AllThreadsCommand);
    759 
    760         return checkReply(performCommand(commandPacket));
    761     }
    762 
    763     /**
    764      * Gets class signature for specified class ID.
    765      *
    766      * @param classID
    767      *            class ID
    768      * @return received class signature
    769      */
    770     public String getClassSignature(long classID) {
    771         // Create new command packet
    772         CommandPacket commandPacket = new CommandPacket(
    773                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    774                 JDWPCommands.ReferenceTypeCommandSet.SignatureCommand);
    775         commandPacket.setNextValueAsReferenceTypeID(classID);
    776         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    777         return replyPacket.getNextValueAsString();
    778     }
    779 
    780     /**
    781      * Returns thread name for specified <code>threadID</code>.
    782      *
    783      * @param threadID
    784      *            thread ID
    785      * @return thread name
    786      */
    787     public String getThreadName(long threadID) {
    788         // Create new command packet
    789         CommandPacket commandPacket = new CommandPacket(
    790                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
    791                 JDWPCommands.ThreadReferenceCommandSet.NameCommand);
    792         commandPacket.setNextValueAsThreadID(threadID);
    793         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    794         return replyPacket.getNextValueAsString();
    795     }
    796 
    797     /**
    798      * Returns thread status for specified <code>threadID</code>.
    799      *
    800      * @param threadID
    801      *            thread ID
    802      * @return thread status
    803      */
    804     public int getThreadStatus(long threadID) {
    805         CommandPacket commandPacket = new CommandPacket(
    806                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
    807                 JDWPCommands.ThreadReferenceCommandSet.StatusCommand);
    808         commandPacket.setNextValueAsThreadID(threadID);
    809         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    810         return replyPacket.getNextValueAsInt();
    811     }
    812 
    813     /**
    814      * Returns suspend count for specified <code>threadID</code>.
    815      *
    816      * @param threadID
    817      *            thread ID
    818      * @return thread's suspend count
    819      */
    820     public int getThreadSuspendCount(long threadID) {
    821         CommandPacket commandPacket = new CommandPacket(
    822                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
    823                 JDWPCommands.ThreadReferenceCommandSet.SuspendCountCommand);
    824         commandPacket.setNextValueAsThreadID(threadID);
    825         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    826         return replyPacket.getNextValueAsInt();
    827     }
    828 
    829     /**
    830      * Returns name of thread group for specified <code>groupID</code>
    831      *
    832      * @param groupID
    833      *            thread group ID
    834      *
    835      * @return name of thread group
    836      */
    837     public String getThreadGroupName(long groupID) {
    838         // Create new command packet
    839         CommandPacket commandPacket = new CommandPacket(
    840                 JDWPCommands.ThreadGroupReferenceCommandSet.CommandSetID,
    841                 JDWPCommands.ThreadGroupReferenceCommandSet.NameCommand);
    842         commandPacket.setNextValueAsReferenceTypeID(groupID);
    843         ReplyPacket replyPacket = checkReply(performCommand(commandPacket));
    844         return replyPacket.getNextValueAsString();
    845     }
    846 
    847     /**
    848      * Gets InterfaceID for specified interface signature.
    849      *
    850      * @param interfaceSignature
    851      *            interface signature
    852      * @return received ClassID
    853      */
    854     public long getInterfaceID(String interfaceSignature) {
    855         return getTypeID(interfaceSignature, JDWPConstants.TypeTag.INTERFACE);
    856     }
    857 
    858     /**
    859      * Gets ArrayID for specified array signature.
    860      *
    861      * @param arraySignature
    862      *            array signature
    863      * @return received ArrayID
    864      */
    865     public long getArrayID(String arraySignature) {
    866         return getTypeID(arraySignature, JDWPConstants.TypeTag.INTERFACE);
    867     }
    868 
    869     /**
    870      * Gets RequestID from specified ReplyPacket.
    871      *
    872      * @param request
    873      *            ReplyPacket with RequestID
    874      * @return received RequestID
    875      */
    876     public int getRequestID(ReplyPacket request) {
    877         return request.getNextValueAsInt();
    878     }
    879 
    880     /**
    881      * Returns FieldID for specified class and field name.
    882      *
    883      * @param classID
    884      *            ClassID to find field
    885      * @param fieldName
    886      *            field name
    887      * @return received FieldID
    888      */
    889     public long getFieldID(long classID, String fieldName) {
    890         ReplyPacket reply = getFieldsInClass(classID);
    891         return getFieldID(reply, fieldName);
    892     }
    893 
    894     /**
    895      * Gets FieldID from ReplyPacket.
    896      *
    897      * @param request
    898      *            ReplyPacket for request
    899      * @param field
    900      *            field name to get ID for
    901      * @return received FieldID
    902      */
    903     public long getFieldID(ReplyPacket request, String field) {
    904         long fieldID = -1;
    905         String fieldName;
    906         // Get fieldID from received packet
    907         int count = request.getNextValueAsInt();
    908         for (int i = 0; i < count; i++) {
    909             fieldID = request.getNextValueAsFieldID();
    910             fieldName = request.getNextValueAsString();
    911             if (field.equals(fieldName)) {
    912                 request.getNextValueAsString();
    913                 request.getNextValueAsInt();
    914                 break;
    915             } else {
    916                 request.getNextValueAsString();
    917                 request.getNextValueAsInt();
    918                 fieldID = 0;
    919                 fieldName = null;
    920             }
    921         }
    922         return fieldID;
    923     }
    924 
    925     /**
    926      * Gets Method ID for specified class and method name.
    927      *
    928      * @param classID
    929      *            class to find method
    930      * @param methodName
    931      *            method name
    932      * @return received MethodID
    933      */
    934     public long getMethodID(long classID, String methodName) {
    935         ReplyPacket reply;
    936         int declared = 0;
    937         String method = null;
    938         long methodID = -1;
    939 
    940         // Get Method reference ID
    941         reply = getMethods(classID);
    942 
    943         // Get methodID from received packet
    944         declared = reply.getNextValueAsInt();
    945         for (int i = 0; i < declared; i++) {
    946             methodID = reply.getNextValueAsMethodID();
    947             method = reply.getNextValueAsString();
    948             if (methodName.equals(method)) {
    949                 // If this method name is the same as requested
    950                 reply.getNextValueAsString();
    951                 reply.getNextValueAsInt();
    952                 break;
    953             } else {
    954                 // If this method name is not the requested one
    955                 reply.getNextValueAsString();
    956                 reply.getNextValueAsInt();
    957                 methodID = -1;
    958                 method = null;
    959             }
    960         }
    961         return methodID;
    962     }
    963 
    964     /**
    965      * Returns method name for specified pair of classID and methodID.
    966      *
    967      * @param classID
    968      * @param methodID
    969      * @return method name
    970      */
    971     public String getMethodName(long classID, long methodID) {
    972         CommandPacket packet = new CommandPacket(
    973                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
    974                 JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
    975         packet.setNextValueAsReferenceTypeID(classID);
    976         ReplyPacket reply = performCommand(packet);
    977 
    978         int declared = reply.getNextValueAsInt();
    979         long mID;
    980         String value = null;
    981         String methodName = "";
    982         for (int i = 0; i < declared; i++) {
    983             mID = reply.getNextValueAsMethodID();
    984             methodName = reply.getNextValueAsString();
    985             reply.getNextValueAsString();
    986             reply.getNextValueAsInt();
    987             if (mID == methodID) {
    988                 value = methodName;
    989                 break;
    990             }
    991         }
    992         return value;
    993     }
    994 
    995     /**
    996      * Sets ClassPrepare event request for given class name pattern.
    997      *
    998      * @param classRegexp
    999      *            Required class pattern. Matches are limited to exact matches
   1000      *            of the given class pattern and matches of patterns that begin
   1001      *            or end with '*'; for example, "*.Foo" or "java.*".
   1002      * @return ReplyPacket for setting request.
   1003      */
   1004     public ReplyPacket setClassPrepared(String classRegexp) {
   1005         // Prepare corresponding event
   1006         byte eventKind = JDWPConstants.EventKind.CLASS_PREPARE;
   1007         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1008         // EventMod[] mods = new EventMod[1];
   1009         EventMod[] mods = new EventMod[] { new EventMod() };
   1010         mods[0].classPattern = classRegexp;
   1011         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1012         Event event = new Event(eventKind, suspendPolicy, mods);
   1013 
   1014         // Set event
   1015         return setEvent(event);
   1016     }
   1017 
   1018     /**
   1019      * Set ClassPrepare event request for given class ID.
   1020      *
   1021      * @param referenceTypeID
   1022      *            class referenceTypeID
   1023      * @return ReplyPacket for setting request
   1024      */
   1025     public ReplyPacket setClassPrepared(long referenceTypeID) {
   1026         // Prepare corresponding event
   1027         byte eventKind = JDWPConstants.EventKind.CLASS_PREPARE;
   1028         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1029         // EventMod[] mods = new EventMod[1];
   1030         EventMod[] mods = new EventMod[] { new EventMod() };
   1031         mods[0].clazz = referenceTypeID;
   1032         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1033         Event event = new Event(eventKind, suspendPolicy, mods);
   1034 
   1035         // Set event
   1036         return setEvent(event);
   1037     }
   1038 
   1039     /**
   1040      * Sets ClassPrepare event request for given source name pattern.
   1041      *
   1042      * @param sourceNamePattern
   1043      *            Required source name pattern. Matches are limited to exact matches
   1044      *            of the given source name pattern and matches of patterns that begin
   1045      *            or end with '*'; for example, "*.Foo" or "java.*".
   1046      * @return ReplyPacket for setting request.
   1047      */
   1048     public ReplyPacket setClassPreparedForSourceNameMatch(String sourceNamePattern) {
   1049         // Prepare corresponding event
   1050         byte eventKind = JDWPConstants.EventKind.CLASS_PREPARE;
   1051         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1052         EventMod[] mods = new EventMod[] { new EventMod() };
   1053         mods[0].sourceNamePattern = sourceNamePattern;
   1054         mods[0].modKind = EventMod.ModKind.SourceNameMatch;
   1055         Event event = new Event(eventKind, suspendPolicy, mods);
   1056 
   1057         // Set event
   1058         return setEvent(event);
   1059     }
   1060 
   1061     /**
   1062      * Sets ClassUnload event request for given class name pattern.
   1063      *
   1064      * @param classSignature
   1065      *            class signature
   1066      * @return ReplyPacket for setting request
   1067      */
   1068     public ReplyPacket setClassUnload(String classRegexp) {
   1069         // Prepare corresponding event
   1070         byte eventKind = JDWPConstants.EventKind.CLASS_UNLOAD;
   1071         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1072         // EventMod[] mods = new EventMod[1];
   1073         EventMod[] mods = new EventMod[] { new EventMod() };
   1074         mods[0].classPattern = classRegexp;
   1075         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1076         Event event = new Event(eventKind, suspendPolicy, mods);
   1077 
   1078         // Set event
   1079         return setEvent(event);
   1080     }
   1081 
   1082     /**
   1083      * Set ClassUnload event request for given class ID.
   1084      *
   1085      * @param referenceTypeID
   1086      *            class referenceTypeID
   1087      * @return ReplyPacket for setting request
   1088      */
   1089     public ReplyPacket setClassUnload(long referenceTypeID) {
   1090         // Prepare corresponding event
   1091         byte eventKind = JDWPConstants.EventKind.CLASS_UNLOAD;
   1092         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1093         // EventMod[] mods = new EventMod[1];
   1094         EventMod[] mods = new EventMod[] { new EventMod() };
   1095         mods[0].clazz = referenceTypeID;
   1096         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1097         Event event = new Event(eventKind, suspendPolicy, mods);
   1098 
   1099         // Set event
   1100         return setEvent(event);
   1101     }
   1102 
   1103     /**
   1104      * Sets ClassLoad event request for given class signature.
   1105      *
   1106      * @param classSignature
   1107      *            class signature
   1108      * @return ReplyPacket for setting request
   1109      */
   1110     public ReplyPacket setClassLoad(String classSignature) {
   1111         long typeID;
   1112 
   1113         // Request referenceTypeID for class
   1114         typeID = getClassID(classSignature);
   1115 
   1116         // Set corresponding event
   1117         return setClassLoad(typeID);
   1118     }
   1119 
   1120     /**
   1121      * Set ClassLoad event request for given class ID.
   1122      *
   1123      * @param referenceTypeID
   1124      *            class referenceTypeID
   1125      * @return ReplyPacket for setting request
   1126      */
   1127     public ReplyPacket setClassLoad(long referenceTypeID) {
   1128         // Prepare corresponding event
   1129         byte eventKind = JDWPConstants.EventKind.CLASS_LOAD;
   1130         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1131         EventMod[] mods = new EventMod[] { new EventMod() };
   1132         mods[0].clazz = referenceTypeID;
   1133         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1134         Event event = new Event(eventKind, suspendPolicy, mods);
   1135 
   1136         // Set event
   1137         return setEvent(event);
   1138     }
   1139 
   1140     /**
   1141      * Set MonitorContendedEnter event request for given class's reference type
   1142      *
   1143      * @param referenceTypeID
   1144      *            class referenceTypeID
   1145      * @return ReplyPacket for setting request
   1146      */
   1147     public ReplyPacket setMonitorContendedEnterForClassOnly(long referenceTypeID) {
   1148         // Prepare corresponding event
   1149         byte eventKind = JDWPConstants.EventKind.MONITOR_CONTENDED_ENTER;
   1150         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1151         EventMod[] mods = new EventMod[] { new EventMod() };
   1152         mods[0].clazz = referenceTypeID;
   1153         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1154         Event event = new Event(eventKind, suspendPolicy, mods);
   1155 
   1156         // Set event
   1157         return setEvent(event);
   1158     }
   1159 
   1160     public ReplyPacket setMonitorContendedEnterForClassMatch(String classRegexp) {
   1161         // Prepare corresponding event
   1162         byte eventKind = JDWPConstants.EventKind.MONITOR_CONTENDED_ENTER;
   1163         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1164         EventMod[] mods = new EventMod[] { new EventMod() };
   1165         mods[0].classPattern = classRegexp;
   1166         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1167         Event event = new Event(eventKind, suspendPolicy, mods);
   1168 
   1169         // Set event
   1170         return setEvent(event);
   1171     }
   1172 
   1173     /**
   1174      * Set MonitorContendedEntered event request for given class's reference type
   1175      *
   1176      * @param referenceTypeID
   1177      *            class referenceTypeID
   1178      * @return ReplyPacket for setting request
   1179      */
   1180     public ReplyPacket setMonitorContendedEnteredForClassOnly(long referenceTypeID) {
   1181         // Prepare corresponding event
   1182         byte eventKind = JDWPConstants.EventKind.MONITOR_CONTENDED_ENTERED;
   1183         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1184         EventMod[] mods = new EventMod[] { new EventMod() };
   1185         mods[0].clazz = referenceTypeID;
   1186         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1187         Event event = new Event(eventKind, suspendPolicy, mods);
   1188 
   1189         // Set event
   1190         return setEvent(event);
   1191     }
   1192 
   1193     public ReplyPacket setMonitorContendedEnteredForClassMatch(String classRegexp) {
   1194         // Prepare corresponding event
   1195         byte eventKind = JDWPConstants.EventKind.MONITOR_CONTENDED_ENTERED;
   1196         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1197         EventMod[] mods = new EventMod[] { new EventMod() };
   1198         mods[0].classPattern = classRegexp;
   1199         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1200         Event event = new Event(eventKind, suspendPolicy, mods);
   1201 
   1202         // Set event
   1203         return setEvent(event);
   1204     }
   1205 
   1206     /**
   1207      * Set MonitorWait event request for given class's reference type
   1208      *
   1209      * @param referenceTypeID
   1210      *            class referenceTypeID
   1211      * @return ReplyPacket for setting request
   1212      */
   1213     public ReplyPacket setMonitorWaitForClassOnly(long referenceTypeID) {
   1214         // Prepare corresponding event
   1215         byte eventKind = JDWPConstants.EventKind.MONITOR_WAIT;
   1216         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1217         EventMod[] mods = new EventMod[] { new EventMod() };
   1218         mods[0].clazz = referenceTypeID;
   1219         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1220         Event event = new Event(eventKind, suspendPolicy, mods);
   1221 
   1222         // Set event
   1223         return setEvent(event);
   1224     }
   1225 
   1226     /**
   1227      * Set MonitorWait event request for given given class name pattern.
   1228      *
   1229      * @param classRegexp
   1230      *            Required class pattern. Matches are limited to exact matches
   1231      *            of the given class pattern and matches of patterns that begin
   1232      *            or end with '*'; for example, "*.Foo" or "java.*".
   1233      * @return ReplyPacket for setting request.
   1234      */
   1235     public ReplyPacket setMonitorWaitForClassMatch(String classRegexp) {
   1236         // Prepare corresponding event
   1237         byte eventKind = JDWPConstants.EventKind.MONITOR_WAIT;
   1238         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1239         EventMod[] mods = new EventMod[] { new EventMod() };
   1240         mods[0].classPattern = classRegexp;
   1241         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1242         Event event = new Event(eventKind, suspendPolicy, mods);
   1243 
   1244         // Set event
   1245         return setEvent(event);
   1246     }
   1247 
   1248     /**
   1249      * Set MonitorWait event request for classes
   1250      * whose name does not match the given restricted regular expression.
   1251      *
   1252      * @param classRegexp
   1253      *            Exclude class pattern. Matches are limited to exact matches
   1254      *            of the given class pattern and matches of patterns that begin
   1255      *            or end with '*'; for example, "*.Foo" or "java.*".
   1256      * @return ReplyPacket for setting request.
   1257      */
   1258     public ReplyPacket setMonitorWaitForClassExclude (String classRegexp) {
   1259         // Prepare corresponding event
   1260         byte eventKind = JDWPConstants.EventKind.MONITOR_WAIT;
   1261         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1262         EventMod[] mods = new EventMod[] { new EventMod() };
   1263         mods[0].classPattern = classRegexp;
   1264         mods[0].modKind = EventMod.ModKind.ClassExclude;
   1265         Event event = new Event(eventKind, suspendPolicy, mods);
   1266 
   1267         // Set event
   1268         return setEvent(event);
   1269     }
   1270 
   1271     /**
   1272      * Set MonitorWaited event request for given class's reference type
   1273      *
   1274      * @param referenceTypeID
   1275      *            class referenceTypeID
   1276      * @return ReplyPacket for setting request
   1277      */
   1278     public ReplyPacket setMonitorWaitedForClassOnly(long referenceTypeID) {
   1279         // Prepare corresponding event
   1280         byte eventKind = JDWPConstants.EventKind.MONITOR_WAITED;
   1281         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1282         EventMod[] mods = new EventMod[] { new EventMod() };
   1283         mods[0].clazz = referenceTypeID;
   1284         mods[0].modKind = EventMod.ModKind.ClassOnly;
   1285         Event event = new Event(eventKind, suspendPolicy, mods);
   1286 
   1287         // Set event
   1288         return setEvent(event);
   1289     }
   1290 
   1291     /**
   1292      * Set MonitorWaited event request for given given source name pattern.
   1293      *
   1294      * @param classRegexp
   1295      *            Required class pattern. Matches are limited to exact matches
   1296      *            of the given class pattern and matches of patterns that begin
   1297      *            or end with '*'; for example, "*.Foo" or "java.*".
   1298      * @return ReplyPacket for setting request.
   1299      */
   1300     public ReplyPacket setMonitorWaitedForClassMatch(String classRegexp) {
   1301         // Prepare corresponding event
   1302         byte eventKind = JDWPConstants.EventKind.MONITOR_WAITED;
   1303         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1304         EventMod[] mods = new EventMod[] { new EventMod() };
   1305         mods[0].classPattern = classRegexp;
   1306         mods[0].modKind = EventMod.ModKind.ClassMatch;
   1307         Event event = new Event(eventKind, suspendPolicy, mods);
   1308 
   1309         // Set event
   1310         return setEvent(event);
   1311     }
   1312 
   1313     /**
   1314      * Set MonitorWaited event request for classes
   1315      * whose name does not match the given restricted regular expression.
   1316      *
   1317      * @param classRegexp
   1318      *            Required class pattern. Matches are limited to exact matches
   1319      *            of the given class pattern and matches of patterns that begin
   1320      *            or end with '*'; for example, "*.Foo" or "java.*".
   1321      * @return ReplyPacket for setting request.
   1322      */
   1323     public ReplyPacket setMonitorWaitedForClassExclude (String classRegexp) {
   1324         // Prepare corresponding event
   1325         byte eventKind = JDWPConstants.EventKind.MONITOR_WAITED;
   1326         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1327         EventMod[] mods = new EventMod[] { new EventMod() };
   1328         mods[0].classPattern = classRegexp;
   1329         mods[0].modKind = EventMod.ModKind.ClassExclude;
   1330         Event event = new Event(eventKind, suspendPolicy, mods);
   1331 
   1332         // Set event
   1333         return setEvent(event);
   1334     }
   1335 
   1336     /**
   1337      * Set event request for given event.
   1338      *
   1339      * @param event
   1340      *            event to set request for
   1341      * @return ReplyPacket for setting request
   1342      */
   1343     public ReplyPacket setEvent(Event event) {
   1344         // Create new command packet
   1345         CommandPacket commandPacket = new CommandPacket(
   1346                 JDWPCommands.EventRequestCommandSet.CommandSetID,
   1347                 JDWPCommands.EventRequestCommandSet.SetCommand);
   1348 
   1349         // Set eventKind
   1350         commandPacket.setNextValueAsByte(event.eventKind);
   1351         // Set suspendPolicy
   1352         commandPacket.setNextValueAsByte(event.suspendPolicy);
   1353 
   1354         // Set modifiers
   1355         commandPacket.setNextValueAsInt(event.modifiers);
   1356 
   1357         for (int i = 0; i < event.modifiers; i++) {
   1358 
   1359             commandPacket.setNextValueAsByte(event.mods[i].modKind);
   1360 
   1361             switch (event.mods[i].modKind) {
   1362             case EventMod.ModKind.Count: {
   1363                 // Case Count
   1364                 commandPacket.setNextValueAsInt(event.mods[i].count);
   1365                 break;
   1366             }
   1367             case EventMod.ModKind.Conditional: {
   1368                 // Case Conditional
   1369                 commandPacket.setNextValueAsInt(event.mods[i].exprID);
   1370                 break;
   1371             }
   1372             case EventMod.ModKind.ThreadOnly: {
   1373                 // Case ThreadOnly
   1374                 commandPacket.setNextValueAsThreadID(event.mods[i].thread);
   1375                 break;
   1376             }
   1377             case EventMod.ModKind.ClassOnly: {
   1378                 // Case ClassOnly
   1379                 commandPacket
   1380                         .setNextValueAsReferenceTypeID(event.mods[i].clazz);
   1381                 break;
   1382             }
   1383             case EventMod.ModKind.ClassMatch: {
   1384                 // Case ClassMatch
   1385                 commandPacket.setNextValueAsString(event.mods[i].classPattern);
   1386                 break;
   1387             }
   1388             case EventMod.ModKind.ClassExclude: {
   1389                 // Case ClassExclude
   1390                 commandPacket.setNextValueAsString(event.mods[i].classPattern);
   1391                 break;
   1392             }
   1393             case EventMod.ModKind.LocationOnly: {
   1394                 // Case LocationOnly
   1395                 commandPacket.setNextValueAsLocation(event.mods[i].loc);
   1396                 break;
   1397             }
   1398             case EventMod.ModKind.ExceptionOnly:
   1399                 // Case ExceptionOnly
   1400                 commandPacket
   1401                         .setNextValueAsReferenceTypeID(event.mods[i].exceptionOrNull);
   1402                 commandPacket.setNextValueAsBoolean(event.mods[i].caught);
   1403                 commandPacket.setNextValueAsBoolean(event.mods[i].uncaught);
   1404                 break;
   1405             case EventMod.ModKind.FieldOnly: {
   1406                 // Case FieldOnly
   1407                 commandPacket
   1408                         .setNextValueAsReferenceTypeID(event.mods[i].declaring);
   1409                 commandPacket.setNextValueAsFieldID(event.mods[i].fieldID);
   1410                 break;
   1411             }
   1412             case EventMod.ModKind.Step: {
   1413                 // Case Step
   1414                 commandPacket.setNextValueAsThreadID(event.mods[i].thread);
   1415                 commandPacket.setNextValueAsInt(event.mods[i].size);
   1416                 commandPacket.setNextValueAsInt(event.mods[i].depth);
   1417                 break;
   1418             }
   1419             case EventMod.ModKind.InstanceOnly: {
   1420                 // Case InstanceOnly
   1421                 commandPacket.setNextValueAsObjectID(event.mods[i].instance);
   1422                 break;
   1423             }
   1424             case EventMod.ModKind.SourceNameMatch: {
   1425                 // Case SourceNameMatch
   1426                 commandPacket.setNextValueAsString(event.mods[i].sourceNamePattern);
   1427             }
   1428             }
   1429         }
   1430 
   1431         // Send packet
   1432         return checkReply(performCommand(commandPacket));
   1433     }
   1434 
   1435     /**
   1436      * Gets method reference by signature.
   1437      *
   1438      * @param classReferenceTypeID
   1439      *            class referenceTypeID.
   1440      * @return ReplyPacket for corresponding command
   1441      */
   1442     public ReplyPacket getMethods(long classReferenceTypeID) {
   1443         // Create new command packet
   1444         CommandPacket commandPacket = new CommandPacket();
   1445 
   1446         // Set command. "5" - is ID of Methods command in ReferenceType Command
   1447         // Set
   1448         commandPacket
   1449                 .setCommand(JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
   1450 
   1451         // Set command set. "2" - is ID of ReferenceType Command Set
   1452         commandPacket
   1453                 .setCommandSet(JDWPCommands.ReferenceTypeCommandSet.CommandSetID);
   1454 
   1455         // Set outgoing data
   1456         // Set referenceTypeID
   1457         commandPacket.setNextValueAsObjectID(classReferenceTypeID);
   1458 
   1459         // Send packet
   1460         return checkReply(performCommand(commandPacket));
   1461     }
   1462 
   1463     /**
   1464      * Gets class reference by signature.
   1465      *
   1466      * @param classSignature
   1467      *            class signature.
   1468      * @return ReplyPacket for corresponding command
   1469      */
   1470     public ReplyPacket getClassBySignature(String classSignature) {
   1471         CommandPacket commandPacket = new CommandPacket(
   1472                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
   1473                 JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
   1474         commandPacket.setNextValueAsString(classSignature);
   1475         return checkReply(performCommand(commandPacket));
   1476     }
   1477 
   1478     /**
   1479      * Gets class fields by class referenceTypeID.
   1480      *
   1481      * @param referenceTypeID
   1482      *            class referenceTypeID.
   1483      * @return ReplyPacket for corresponding command
   1484      */
   1485     public ReplyPacket getFieldsInClass(long referenceTypeID) {
   1486         CommandPacket commandPacket = new CommandPacket(
   1487                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
   1488                 JDWPCommands.ReferenceTypeCommandSet.FieldsCommand);
   1489         commandPacket.setNextValueAsReferenceTypeID(referenceTypeID);
   1490         return checkReply(performCommand(commandPacket));
   1491     }
   1492 
   1493     /**
   1494      * Sets exception event request for given exception class signature.
   1495      *
   1496      * @param exceptionSignature
   1497      *            exception signature.
   1498      * @param caught
   1499      *            is exception caught
   1500      * @param uncaught
   1501      *            is exception uncaught
   1502      * @return ReplyPacket for corresponding command
   1503      */
   1504     public ReplyPacket setException(String exceptionSignature, boolean caught,
   1505             boolean uncaught) {
   1506         // Request referenceTypeID for exception
   1507         long typeID = getClassID(exceptionSignature);
   1508         return setException(typeID, caught, uncaught);
   1509     }
   1510 
   1511     /**
   1512      * Sets exception event request for given exception class ID.
   1513      *
   1514      * @param exceptionID
   1515      *            exception referenceTypeID.
   1516      * @param caught
   1517      *            is exception caught
   1518      * @param uncaught
   1519      *            is exception uncaught
   1520      * @return ReplyPacket for corresponding command
   1521      */
   1522     public ReplyPacket setException(long exceptionID, boolean caught,
   1523             boolean uncaught) {
   1524         // Prepare corresponding event
   1525         byte eventKind = JDWPConstants.EventKind.EXCEPTION;
   1526         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1527         EventMod[] mods = new EventMod[1];
   1528         mods[0] = new EventMod();
   1529         mods[0].modKind = EventMod.ModKind.ExceptionOnly;
   1530         mods[0].caught = caught;
   1531         mods[0].uncaught = uncaught;
   1532         mods[0].exceptionOrNull = exceptionID;
   1533         Event event = new Event(eventKind, suspendPolicy, mods);
   1534 
   1535         return setEvent(event);
   1536     }
   1537 
   1538     /**
   1539      * Sets exception event request for given exception class signature.
   1540      *
   1541      * @param exceptionSignature
   1542      *            exception signature.
   1543      * @param caught
   1544      *            is exception caught
   1545      * @param uncaught
   1546      *            is exception uncaught
   1547      * @param count
   1548      *            Limit the requested event to be reported at most once after a
   1549      *            given number of occurrences
   1550      * @return ReplyPacket for corresponding command
   1551      */
   1552     public ReplyPacket setCountableException(String exceptionSignature,
   1553             boolean caught, boolean uncaught, int count) {
   1554         // Request referenceTypeID for exception
   1555         long exceptionID = getClassID(exceptionSignature);
   1556         byte eventKind = JDWPConstants.EventKind.EXCEPTION;
   1557         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1558         EventMod[] mods = new EventMod[2];
   1559         mods[0] = new EventMod();
   1560         mods[0].modKind = EventMod.ModKind.ExceptionOnly;
   1561         mods[0].caught = caught;
   1562         mods[0].uncaught = uncaught;
   1563         mods[0].exceptionOrNull = exceptionID;
   1564 
   1565         mods[1] = new EventMod();
   1566         mods[1].modKind = EventMod.ModKind.Count;
   1567         mods[1].count = count;
   1568         Event event = new Event(eventKind, suspendPolicy, mods);
   1569 
   1570         return setEvent(event);
   1571     }
   1572 
   1573     /**
   1574      * Sets METHOD_ENTRY event request for specified class name pattern.
   1575      *
   1576      * @param classRegexp
   1577      *            class name pattern or null for no pattern
   1578      *
   1579      * @return ReplyPacket for corresponding command
   1580      */
   1581     public ReplyPacket setMethodEntry(String classRegexp) {
   1582         // Prepare corresponding event
   1583         byte eventKind = JDWPConstants.EventKind.METHOD_ENTRY;
   1584         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1585         EventMod[] mods = null;
   1586         if (classRegexp == null) {
   1587             mods = new EventMod[0];
   1588         } else {
   1589             mods = new EventMod[1];
   1590             mods[0] = new EventMod();
   1591             mods[0].modKind = EventMod.ModKind.ClassMatch;
   1592             mods[0].classPattern = classRegexp;
   1593         }
   1594         Event event = new Event(eventKind, suspendPolicy, mods);
   1595 
   1596         return setEvent(event);
   1597     }
   1598 
   1599     /**
   1600      * Sets METHOD_ENTRY event request for specified class name pattern.
   1601      *
   1602      * @param classRegexp
   1603      *            class name pattern or null for no pattern
   1604      * @param count
   1605      *            Limit the requested event to be reported at most once after a
   1606      *            given number of occurrences
   1607      * @return ReplyPacket for corresponding command
   1608      */
   1609     public ReplyPacket setCountableMethodEntry(String classRegexp, int count) {
   1610         byte eventKind = JDWPConstants.EventKind.METHOD_ENTRY;
   1611         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1612         EventMod[] mods = null;
   1613         if (classRegexp == null) {
   1614             mods = new EventMod[] { new EventMod() };
   1615             mods[0].modKind = EventMod.ModKind.Count;
   1616             mods[0].count = count;
   1617         } else {
   1618             mods = new EventMod[2];
   1619             mods[0] = new EventMod();
   1620             mods[0].modKind = EventMod.ModKind.ClassMatch;
   1621             mods[0].classPattern = classRegexp;
   1622 
   1623             mods[1] = new EventMod();
   1624             mods[1].modKind = EventMod.ModKind.Count;
   1625             mods[1].count = count;
   1626         }
   1627         Event event = new Event(eventKind, suspendPolicy, mods);
   1628 
   1629         return setEvent(event);
   1630     }
   1631 
   1632     /**
   1633      * Sets METHOD_EXIT event request for specified class name pattern.
   1634      *
   1635      * @param classRegexp
   1636      *            class name pattern or null for no pattern
   1637      *
   1638      * @return ReplyPacket for corresponding command
   1639      */
   1640     public ReplyPacket setMethodExit(String classRegexp) {
   1641         // Prepare corresponding event
   1642         byte eventKind = JDWPConstants.EventKind.METHOD_EXIT;
   1643         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1644         EventMod[] mods = null;
   1645         if (classRegexp == null) {
   1646             mods = new EventMod[0];
   1647         } else {
   1648             mods = new EventMod[1];
   1649             mods[0] = new EventMod();
   1650             mods[0].modKind = EventMod.ModKind.ClassMatch;
   1651             mods[0].classPattern = classRegexp;
   1652         }
   1653         Event event = new Event(eventKind, suspendPolicy, mods);
   1654 
   1655         return setEvent(event);
   1656     }
   1657 
   1658     /**
   1659      * Sets METHOD_EXIT_WITH_RETURN_VALUE event request for specified class name pattern.
   1660      *
   1661      * @param classRegexp
   1662      *            class name pattern or null for no pattern
   1663      *
   1664      * @return ReplyPacket for corresponding command
   1665      */
   1666     public ReplyPacket setMethodExitWithReturnValue(String classRegexp) {
   1667         // Prepare corresponding event
   1668         byte eventKind = JDWPConstants.EventKind.METHOD_EXIT_WITH_RETURN_VALUE;
   1669         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1670         EventMod[] mods = null;
   1671         if (classRegexp == null) {
   1672             mods = new EventMod[0];
   1673         } else {
   1674             mods = new EventMod[1];
   1675             mods[0] = new EventMod();
   1676             mods[0].modKind = EventMod.ModKind.ClassMatch;
   1677             mods[0].classPattern = classRegexp;
   1678         }
   1679         Event event = new Event(eventKind, suspendPolicy, mods);
   1680 
   1681         return setEvent(event);
   1682     }
   1683 
   1684     /**
   1685      * Sets METHOD_EXIT event request for specified class name pattern.
   1686      *
   1687      * @param classRegexp
   1688      *            classRegexp class name pattern or null for no pattern
   1689      * @param count
   1690      *            Limit the requested event to be reported at most once after a
   1691      *            given number of occurrences
   1692      * @return ReplyPacket for corresponding command
   1693      */
   1694     public ReplyPacket setCountableMethodExit(String classRegexp, int count) {
   1695         byte eventKind = JDWPConstants.EventKind.METHOD_EXIT;
   1696         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1697         EventMod[] mods = null;
   1698         if (classRegexp == null) {
   1699             mods = new EventMod[] { new EventMod() };
   1700             mods[0].modKind = EventMod.ModKind.Count;
   1701             mods[0].count = count;
   1702         } else {
   1703             mods = new EventMod[2];
   1704             mods[0] = new EventMod();
   1705             mods[0].modKind = EventMod.ModKind.ClassMatch;
   1706             mods[0].classPattern = classRegexp;
   1707 
   1708             mods[1] = new EventMod();
   1709             mods[1].modKind = EventMod.ModKind.Count;
   1710             mods[1].count = count;
   1711         }
   1712         Event event = new Event(eventKind, suspendPolicy, mods);
   1713 
   1714         return setEvent(event);
   1715 
   1716     }
   1717 
   1718     /**
   1719      * Sets field access event request for specified class signature and field
   1720      * name.
   1721      *
   1722      * @param classTypeTag
   1723      *            class Type Tag (class/interface/array)
   1724      * @param classSignature
   1725      *            class signature
   1726      * @param fieldName
   1727      *            field name
   1728      * @return ReplyPacket if breakpoint is set
   1729      * @throws ReplyErrorCodeException
   1730      */
   1731     public ReplyPacket setFieldAccess(String classSignature, byte classTypeTag,
   1732             String fieldName) throws ReplyErrorCodeException {
   1733         ReplyPacket request = null;
   1734         long typeID = -1;
   1735         long fieldID = -1;
   1736 
   1737         // Request referenceTypeID for class
   1738         typeID = getClassID(classSignature);
   1739 
   1740         // Request fields in class
   1741         request = getFieldsInClass(typeID);
   1742 
   1743         // Get fieldID from received packet
   1744         fieldID = getFieldID(request, fieldName);
   1745 
   1746         // Prepare corresponding event
   1747         byte eventKind = JDWPConstants.EventKind.FIELD_ACCESS;
   1748         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1749         // EventMod[] mods = new EventMod[1];
   1750         EventMod[] mods = new EventMod[] { new EventMod() };
   1751         mods[0].fieldID = fieldID;
   1752         mods[0].declaring = typeID;
   1753         mods[0].modKind = EventMod.ModKind.FieldOnly;
   1754         Event event = new Event(eventKind, suspendPolicy, mods);
   1755 
   1756         // Set exception
   1757         return setEvent(event);
   1758     }
   1759 
   1760     /**
   1761      * Sets field modification event request for specified class signature and
   1762      * field name.
   1763      *
   1764      * @param classTypeTag
   1765      *            class Type Tag (class/interface/array)
   1766      * @param classSignature
   1767      *            class signature
   1768      * @param fieldName
   1769      *            field name
   1770      * @return ReplyPacket for corresponding command
   1771      * @throws ReplyErrorCodeException
   1772      */
   1773     public ReplyPacket setFieldModification(String classSignature,
   1774             byte classTypeTag, String fieldName) throws ReplyErrorCodeException {
   1775         ReplyPacket request = null;
   1776         long typeID = -1;
   1777         long fieldID = -1;
   1778 
   1779         // Request referenceTypeID for class
   1780         typeID = getClassID(classSignature);
   1781 
   1782         // Request fields in class
   1783         request = getFieldsInClass(typeID);
   1784 
   1785         // Get fieldID from received packet
   1786         fieldID = getFieldID(request, fieldName);
   1787 
   1788         // Prepare corresponding event
   1789         byte eventKind = JDWPConstants.EventKind.FIELD_MODIFICATION;
   1790         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1791         // EventMod[] mods = new EventMod[1];
   1792         EventMod[] mods = new EventMod[] { new EventMod() };
   1793         mods[0].fieldID = fieldID;
   1794         mods[0].declaring = typeID;
   1795         mods[0].modKind = EventMod.ModKind.FieldOnly;
   1796         Event event = new Event(eventKind, suspendPolicy, mods);
   1797 
   1798         // Set event
   1799         return setEvent(event);
   1800     }
   1801 
   1802     /**
   1803      * Sets step event request for given thread ID.
   1804      *
   1805      * @param threadID
   1806      *          the ID of the thread
   1807      * @param stepSize
   1808      *          the step size
   1809      * @param stepDepth
   1810      *          the step depth
   1811      * @return ReplyPacket for corresponding command
   1812      */
   1813     public ReplyPacket setStep(long threadID, int stepSize, int stepDepth) {
   1814         // Prepare corresponding event
   1815         byte eventKind = JDWPConstants.EventKind.SINGLE_STEP;
   1816         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1817         EventMod[] mods = new EventMod[] { new EventMod() };
   1818         mods[0].thread = threadID;
   1819         mods[0].modKind = EventMod.ModKind.Step;
   1820         mods[0].size = stepSize;
   1821         mods[0].depth = stepDepth;
   1822         Event event = new Event(eventKind, suspendPolicy, mods);
   1823 
   1824         // Set event
   1825         return setEvent(event);
   1826     }
   1827 
   1828     /**
   1829      * Sets SINGLE_STEP event request for classes whose name does not match the
   1830      * given restricted regular expression
   1831      *
   1832      * @param classRegexp
   1833      *            Disallowed class patterns. Matches are limited to exact
   1834      *            matches of the given class pattern and matches of patterns
   1835      *            that begin or end with '*'; for example, "*.Foo" or "java.*".
   1836      * @param stepSize
   1837      * @param stepDepth
   1838      * @return ReplyPacket for setting request.
   1839      */
   1840     public ReplyPacket setStep(String[] classRegexp, long threadID,
   1841             int stepSize, int stepDepth) {
   1842         // Prepare corresponding event
   1843         byte eventKind = JDWPConstants.EventKind.SINGLE_STEP;
   1844         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1845         int modsSize = classRegexp.length + 1;
   1846         EventMod[] mods = new EventMod[modsSize];
   1847         for (int i = 0; i < classRegexp.length; i++) {
   1848             mods[i] = new EventMod();
   1849             mods[i].classPattern = classRegexp[i];
   1850             mods[i].modKind = EventMod.ModKind.ClassExclude;
   1851         }
   1852 
   1853         int index = modsSize - 1;
   1854         mods[index] = new EventMod();
   1855         mods[index].modKind = EventMod.ModKind.Step;
   1856         mods[index].thread = threadID;
   1857         mods[index].size = stepSize;
   1858         mods[index].depth = stepDepth;
   1859 
   1860         Event event = new Event(eventKind, suspendPolicy, mods);
   1861 
   1862         // Set event
   1863         return setEvent(event);
   1864     }
   1865 
   1866     /**
   1867      * Sets THREAD_START event request.
   1868      *
   1869      * @return ReplyPacket for corresponding command
   1870      */
   1871     public ReplyPacket setThreadStart() {
   1872         // Prepare corresponding event
   1873         byte eventKind = JDWPConstants.EventKind.THREAD_START;
   1874         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1875         EventMod[] mods = new EventMod[0];
   1876         Event event = new Event(eventKind, suspendPolicy, mods);
   1877 
   1878         return setEvent(event);
   1879     }
   1880 
   1881     /**
   1882      * Sets THREAD_END event request.
   1883      *
   1884      * @return ReplyPacket for corresponding command
   1885      */
   1886     public ReplyPacket setThreadEnd() {
   1887         // Prepare corresponding event
   1888         byte eventKind = JDWPConstants.EventKind.THREAD_END;
   1889         byte suspendPolicy = JDWPConstants.SuspendPolicy.ALL;
   1890         EventMod[] mods = new EventMod[0];
   1891         Event event = new Event(eventKind, suspendPolicy, mods);
   1892 
   1893         return setEvent(event);
   1894     }
   1895 
   1896     /**
   1897      * Clear an event request for specified request ID.
   1898      *
   1899      * @param eventKind
   1900      *            event type to clear
   1901      * @param requestID
   1902      *            request ID to clear
   1903      * @return ReplyPacket for corresponding command
   1904      */
   1905     public ReplyPacket clearEvent(byte eventKind, int requestID) {
   1906         // Create new command packet
   1907         CommandPacket commandPacket = new CommandPacket();
   1908 
   1909         // Set command. "2" - is ID of Clear command in EventRequest Command Set
   1910         commandPacket
   1911                 .setCommand(JDWPCommands.EventRequestCommandSet.ClearCommand);
   1912 
   1913         // Set command set. "15" - is ID of EventRequest Command Set
   1914         commandPacket
   1915                 .setCommandSet(JDWPCommands.EventRequestCommandSet.CommandSetID);
   1916 
   1917         // Set outgoing data
   1918         // Set event type to clear
   1919         commandPacket.setNextValueAsByte(eventKind);
   1920 
   1921         // Set ID of request to clear
   1922         commandPacket.setNextValueAsInt(requestID);
   1923 
   1924         // Send packet
   1925         return checkReply(performCommand(commandPacket));
   1926     }
   1927 
   1928     /**
   1929      * Sends CommandPacket to debuggee VM and waits for ReplyPacket using
   1930      * default timeout. All thrown exceptions are wrapped into
   1931      * TestErrorException. Consider using checkReply() for checking error code
   1932      * in reply packet.
   1933      *
   1934      * @param command
   1935      *            Command packet to be sent
   1936      * @return received ReplyPacket
   1937      */
   1938     public ReplyPacket performCommand(CommandPacket command)
   1939             throws TestErrorException {
   1940         ReplyPacket replyPacket = null;
   1941         try {
   1942             replyPacket = packetDispatcher.performCommand(command);
   1943         } catch (IOException e) {
   1944             throw new TestErrorException(e);
   1945         } catch (InterruptedException e) {
   1946             throw new TestErrorException(e);
   1947         }
   1948 
   1949         return replyPacket;
   1950     }
   1951 
   1952     /**
   1953      * Sends CommandPacket to debuggee VM and waits for ReplyPacket using
   1954      * specified timeout.
   1955      *
   1956      * @param command
   1957      *            Command packet to be sent
   1958      * @param timeout
   1959      *            Timeout in milliseconds for waiting reply packet
   1960      * @return received ReplyPacket
   1961      * @throws InterruptedException
   1962      * @throws IOException
   1963      * @throws TimeoutException
   1964      */
   1965     public ReplyPacket performCommand(CommandPacket command, long timeout)
   1966             throws IOException, InterruptedException, TimeoutException {
   1967 
   1968         return packetDispatcher.performCommand(command, timeout);
   1969     }
   1970 
   1971     /**
   1972      * Sends CommandPacket to debuggee VM without waiting for the reply. This
   1973      * method is intended for special cases when there is need to divide
   1974      * command's performing into two actions: command's sending and receiving
   1975      * reply (e.g. for asynchronous JDWP commands' testing). After this method
   1976      * the 'receiveReply()' method must be used latter for receiving reply for
   1977      * sent command. It is NOT recommended to use this method for usual cases -
   1978      * 'performCommand()' method must be used.
   1979      *
   1980      * @param command
   1981      *            Command packet to be sent
   1982      * @return command ID of sent command
   1983      * @throws IOException
   1984      *             if any connection error occurred
   1985      */
   1986     public int sendCommand(CommandPacket command) throws IOException {
   1987         return packetDispatcher.sendCommand(command);
   1988     }
   1989 
   1990     /**
   1991      * Waits for reply for command which was sent before by 'sendCommand()'
   1992      * method. Default timeout is used as time limit for waiting. This method
   1993      * (jointly with 'sendCommand()') is intended for special cases when there
   1994      * is need to divide command's performing into two actions: command's
   1995      * sending and receiving reply (e.g. for asynchronous JDWP commands'
   1996      * testing). It is NOT recommended to use 'sendCommand()- receiveReply()'
   1997      * pair for usual cases - 'performCommand()' method must be used.
   1998      *
   1999      * @param commandId
   2000      *            Command ID of sent before command, reply from which is
   2001      *            expected to be received
   2002      * @return received ReplyPacket
   2003      * @throws IOException
   2004      *             if any connection error occurred
   2005      * @throws InterruptedException
   2006      *             if reply packet's waiting was interrupted
   2007      * @throws TimeoutException
   2008      *             if timeout exceeded
   2009      */
   2010     public ReplyPacket receiveReply(int commandId) throws InterruptedException,
   2011             IOException, TimeoutException {
   2012         return packetDispatcher.receiveReply(commandId, config.getTimeout());
   2013     }
   2014 
   2015     /**
   2016      * Waits for reply for command which was sent before by 'sendCommand()'
   2017      * method. Specified timeout is used as time limit for waiting. This method
   2018      * (jointly with 'sendCommand()') is intended for special cases when there
   2019      * is need to divide command's performing into two actions: command's
   2020      * sending and receiving reply (e.g. for asynchronous JDWP commands'
   2021      * testing). It is NOT recommended to use 'sendCommand()- receiveReply()'
   2022      * pair for usual cases - 'performCommand()' method must be used.
   2023      *
   2024      * @param commandId
   2025      *            Command ID of sent before command, reply from which is
   2026      *            expected to be received
   2027      * @param timeout
   2028      *            Specified timeout in milliseconds to wait for reply
   2029      * @return received ReplyPacket
   2030      * @throws IOException
   2031      *             if any connection error occurred
   2032      * @throws InterruptedException
   2033      *             if reply packet's waiting was interrupted
   2034      * @throws TimeoutException
   2035      *             if timeout exceeded
   2036      */
   2037     public ReplyPacket receiveReply(int commandId, long timeout)
   2038             throws InterruptedException, IOException, TimeoutException {
   2039         return packetDispatcher.receiveReply(commandId, timeout);
   2040     }
   2041 
   2042     /**
   2043      * Waits for EventPacket using default timeout. All thrown exceptions are
   2044      * wrapped into TestErrorException.
   2045      *
   2046      * @return received EventPacket
   2047      */
   2048     public EventPacket receiveEvent() throws TestErrorException {
   2049         try {
   2050             return receiveEvent(config.getTimeout());
   2051         } catch (IOException e) {
   2052             throw new TestErrorException(e);
   2053         } catch (InterruptedException e) {
   2054             throw new TestErrorException(e);
   2055         }
   2056     }
   2057 
   2058     /**
   2059      * Waits for EventPacket using specified timeout.
   2060      *
   2061      * @param timeout
   2062      *            Timeout in milliseconds to wait for event
   2063      * @return received EventPacket
   2064      * @throws IOException
   2065      * @throws InterruptedException
   2066      * @throws TimeoutException
   2067      */
   2068     public EventPacket receiveEvent(long timeout) throws IOException,
   2069             InterruptedException, TimeoutException {
   2070 
   2071         return packetDispatcher.receiveEvent(timeout);
   2072     }
   2073 
   2074     /**
   2075      * Waits for expected event kind using default timeout. Throws
   2076      * TestErrorException if received event is not of expected kind or not a
   2077      * single event in the received event set.
   2078      *
   2079      * @param eventKind
   2080      *            Type of expected event -
   2081      * @see JDWPConstants.EventKind
   2082      * @return received EventPacket
   2083      */
   2084     public EventPacket receiveCertainEvent(byte eventKind)
   2085             throws TestErrorException {
   2086 
   2087         EventPacket eventPacket = receiveEvent();
   2088         ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(eventPacket);
   2089 
   2090         if (parsedEvents.length == 1
   2091                 && parsedEvents[0].getEventKind() == eventKind)
   2092             return eventPacket;
   2093 
   2094         switch (parsedEvents.length) {
   2095         case (0):
   2096             throw new TestErrorException(
   2097                     "Unexpected event received: zero length");
   2098         case (1):
   2099             throw new TestErrorException("Unexpected event received: "
   2100                     + "expected " + JDWPConstants.EventKind.getName(eventKind)
   2101                     + " (" + eventKind + ") but received "
   2102                     + JDWPConstants.EventKind.getName(parsedEvents[0].getEventKind())
   2103                     + " (" + parsedEvents[0].getEventKind() + ")");
   2104         default:
   2105             throw new TestErrorException(
   2106                     "Unexpected event received: Event was grouped in a composite event");
   2107         }
   2108     }
   2109 
   2110     /**
   2111      * Returns JDWP connection channel used by this VmMirror.
   2112      *
   2113      * @return connection channel
   2114      */
   2115     public TransportWrapper getConnection() {
   2116         return connection;
   2117     }
   2118 
   2119     /**
   2120      * Sets established connection channel to be used with this VmMirror and
   2121      * starts reading packets.
   2122      *
   2123      * @param connection
   2124      *            connection channel to be set
   2125      */
   2126     public void setConnection(TransportWrapper connection) {
   2127         this.connection = connection;
   2128         packetDispatcher = new PacketDispatcher(connection, config, logWriter);
   2129     }
   2130 
   2131     /**
   2132      * Closes connection channel used with this VmMirror and stops reading
   2133      * packets.
   2134      *
   2135      */
   2136     public void closeConnection() throws IOException {
   2137         if (connection != null && connection.isOpen())
   2138             connection.close();
   2139 
   2140         // wait for packetDispatcher is closed
   2141         if (packetDispatcher != null) {
   2142             try {
   2143                 packetDispatcher.join();
   2144             } catch (InterruptedException e) {
   2145                 // do nothing but print a stack trace
   2146                 e.printStackTrace();
   2147             }
   2148         }
   2149     }
   2150 
   2151     /**
   2152      * Returns the count of frames on this thread's stack
   2153      *
   2154      * @param threadID
   2155      *            The thread object ID.
   2156      * @return The count of frames on this thread's stack
   2157      */
   2158     public final int getFrameCount(long threadID) {
   2159         CommandPacket command = new CommandPacket(
   2160                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
   2161                 JDWPCommands.ThreadReferenceCommandSet.FrameCountCommand);
   2162         command.setNextValueAsThreadID(threadID);
   2163         ReplyPacket reply = checkReply(performCommand(command));
   2164         return reply.getNextValueAsInt();
   2165     }
   2166 
   2167     /**
   2168      * Returns a list containing all frames of a certain thread
   2169      *
   2170      * @param threadID
   2171      *            ID of the thread
   2172      * @return A list of frames
   2173      */
   2174     public final List getAllThreadFrames(long threadID) {
   2175         if (!isThreadSuspended(threadID)) {
   2176             return new ArrayList(0);
   2177         }
   2178 
   2179         ReplyPacket reply = getThreadFrames(threadID, 0, -1);
   2180         int framesCount = reply.getNextValueAsInt();
   2181         if (framesCount == 0) {
   2182             return new ArrayList(0);
   2183         }
   2184 
   2185         ArrayList<Frame> frames = new ArrayList<Frame>(framesCount);
   2186         for (int i = 0; i < framesCount; i++) {
   2187             Frame frame = new Frame();
   2188             frame.setThreadID(threadID);
   2189             frame.setID(reply.getNextValueAsFrameID());
   2190             frame.setLocation(reply.getNextValueAsLocation());
   2191             frames.add(frame);
   2192         }
   2193 
   2194         return frames;
   2195     }
   2196 
   2197     /**
   2198      * Returns a set of frames of a certain suspended thread
   2199      *
   2200      * @param threadID
   2201      *            ID of the thread whose frames to obtain
   2202      * @param startIndex
   2203      *            The index of the first frame to retrieve.
   2204      * @param length
   2205      *            The count of frames to retrieve (-1 means all remaining).
   2206      * @return ReplyPacket for corresponding command
   2207      */
   2208     public final ReplyPacket getThreadFrames(long threadID, int startIndex,
   2209             int length) {
   2210         CommandPacket command = new CommandPacket(
   2211                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
   2212                 JDWPCommands.ThreadReferenceCommandSet.FramesCommand);
   2213         command.setNextValueAsThreadID(threadID);
   2214         command.setNextValueAsInt(startIndex); // start frame's index
   2215         command.setNextValueAsInt(length); // get all remaining frames;
   2216         return checkReply(performCommand(command));
   2217     }
   2218 
   2219     /**
   2220      * Returns variable information for the method
   2221      *
   2222      * @param classID
   2223      *            The class ID
   2224      * @param methodID
   2225      *            The method ID
   2226      * @return A list containing all variables (arguments and locals) declared
   2227      *         within the method.
   2228      */
   2229     public final List getVariableTable(long classID, long methodID) {
   2230         CommandPacket command = new CommandPacket(
   2231                 JDWPCommands.MethodCommandSet.CommandSetID,
   2232                 JDWPCommands.MethodCommandSet.VariableTableCommand);
   2233         command.setNextValueAsReferenceTypeID(classID);
   2234         command.setNextValueAsMethodID(methodID);
   2235         // ReplyPacket reply =
   2236         // debuggeeWrapper.vmMirror.checkReply(debuggeeWrapper.vmMirror.performCommand(command));
   2237         ReplyPacket reply = performCommand(command);
   2238         if (reply.getErrorCode() == JDWPConstants.Error.ABSENT_INFORMATION
   2239                 || reply.getErrorCode() == JDWPConstants.Error.NATIVE_METHOD) {
   2240             return null;
   2241         }
   2242 
   2243         checkReply(reply);
   2244 
   2245         reply.getNextValueAsInt(); // argCnt, is not used
   2246         int slots = reply.getNextValueAsInt();
   2247         if (slots == 0) {
   2248             return null;
   2249         }
   2250 
   2251         ArrayList<Variable> vars = new ArrayList<Variable>(slots);
   2252         for (int i = 0; i < slots; i++) {
   2253             Variable var = new Frame().new Variable();
   2254             var.setCodeIndex(reply.getNextValueAsLong());
   2255             var.setName(reply.getNextValueAsString());
   2256             var.setSignature(reply.getNextValueAsString());
   2257             var.setLength(reply.getNextValueAsInt());
   2258             var.setSlot(reply.getNextValueAsInt());
   2259             vars.add(var);
   2260         }
   2261 
   2262         return vars;
   2263     }
   2264 
   2265     /**
   2266      * Returns values of local variables in a given frame
   2267      *
   2268      * @param frame
   2269      *            Frame whose variables to get
   2270      * @return An array of Value objects
   2271      */
   2272     public final Value[] getFrameValues(Frame frame) {
   2273         CommandPacket command = new CommandPacket(
   2274                 JDWPCommands.StackFrameCommandSet.CommandSetID,
   2275                 JDWPCommands.StackFrameCommandSet.GetValuesCommand);
   2276         command.setNextValueAsThreadID(frame.getThreadID());
   2277         command.setNextValueAsFrameID(frame.getID());
   2278         int slots = frame.getVars().size();
   2279         command.setNextValueAsInt(slots);
   2280         Iterator it = frame.getVars().iterator();
   2281         while (it.hasNext()) {
   2282             Frame.Variable var = (Frame.Variable) it.next();
   2283             command.setNextValueAsInt(var.getSlot());
   2284             command.setNextValueAsByte(var.getTag());
   2285         }
   2286 
   2287         ReplyPacket reply = checkReply(performCommand(command));
   2288         reply.getNextValueAsInt(); // number of values , is not used
   2289         Value[] values = new Value[slots];
   2290         for (int i = 0; i < slots; i++) {
   2291             values[i] = reply.getNextValueAsValue();
   2292         }
   2293 
   2294         return values;
   2295     }
   2296 
   2297     /**
   2298      * Returns the immediate superclass of a class
   2299      *
   2300      * @param classID
   2301      *            The class ID whose superclass ID is to get
   2302      * @return The superclass ID (null if the class ID for java.lang.Object is
   2303      *         specified).
   2304      */
   2305     public final long getSuperclassId(long classID) {
   2306         CommandPacket command = new CommandPacket(
   2307                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
   2308                 JDWPCommands.ClassTypeCommandSet.SuperclassCommand);
   2309         command.setNextValueAsClassID(classID);
   2310         ReplyPacket reply = checkReply(performCommand(command));
   2311         return reply.getNextValueAsClassID();
   2312     }
   2313 
   2314     /**
   2315      * Returns the runtime type of the object
   2316      *
   2317      * @param objectID
   2318      *            The object ID
   2319      * @return The runtime reference type.
   2320      */
   2321     public final long getReferenceType(long objectID) {
   2322         CommandPacket command = new CommandPacket(
   2323                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
   2324                 JDWPCommands.ObjectReferenceCommandSet.ReferenceTypeCommand);
   2325         command.setNextValueAsObjectID(objectID);
   2326         ReplyPacket reply = checkReply(performCommand(command));
   2327         reply.getNextValueAsByte();
   2328         return reply.getNextValueAsLong();
   2329     }
   2330 
   2331     /**
   2332      * Returns the class object corresponding to this type
   2333      *
   2334      * @param refType
   2335      *            The reference type ID.
   2336      * @return The class object.
   2337      */
   2338     public final long getClassObjectId(long refType) {
   2339         CommandPacket command = new CommandPacket(
   2340                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
   2341                 JDWPCommands.ReferenceTypeCommandSet.ClassObjectCommand);
   2342         command.setNextValueAsReferenceTypeID(refType);
   2343         ReplyPacket reply = checkReply(performCommand(command));
   2344         return reply.getNextValueAsObjectID();
   2345     }
   2346 
   2347     /**
   2348      * Returns line number information for the method, if present.
   2349      *
   2350      * @param refType
   2351      *            The class ID
   2352      * @param methodID
   2353      *            The method ID
   2354      * @return ReplyPacket for corresponding command.
   2355      */
   2356     public final ReplyPacket getLineTable(long refType, long methodID) {
   2357         CommandPacket command = new CommandPacket(
   2358                 JDWPCommands.MethodCommandSet.CommandSetID,
   2359                 JDWPCommands.MethodCommandSet.LineTableCommand);
   2360         command.setNextValueAsReferenceTypeID(refType);
   2361         command.setNextValueAsMethodID(methodID);
   2362         // ReplyPacket reply =
   2363         // debuggeeWrapper.vmMirror.checkReply(debuggeeWrapper.vmMirror.performCommand(command));
   2364         // it is impossible to obtain line table information from native
   2365         // methods, so reply checking is not performed
   2366         ReplyPacket reply = performCommand(command);
   2367         if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
   2368             if (reply.getErrorCode() == JDWPConstants.Error.NATIVE_METHOD) {
   2369                 return reply;
   2370             }
   2371         }
   2372 
   2373         return checkReply(reply);
   2374     }
   2375 
   2376     /**
   2377      * Returns the value of one or more instance fields.
   2378      *
   2379      * @param objectID
   2380      *            The object ID
   2381      * @param fieldIDs
   2382      *            IDs of fields to get
   2383      * @return An array of Value objects representing each field's value
   2384      */
   2385     public final Value[] getObjectReferenceValues(long objectID, long[] fieldIDs) {
   2386         int fieldsCount = fieldIDs.length;
   2387         if (fieldsCount == 0) {
   2388             return null;
   2389         }
   2390 
   2391         CommandPacket command = new CommandPacket(
   2392                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
   2393                 JDWPCommands.ObjectReferenceCommandSet.GetValuesCommand);
   2394         command.setNextValueAsReferenceTypeID(objectID);
   2395         command.setNextValueAsInt(fieldsCount);
   2396         for (int i = 0; i < fieldsCount; i++) {
   2397             command.setNextValueAsFieldID(fieldIDs[i]);
   2398         }
   2399 
   2400         ReplyPacket reply = checkReply(performCommand(command));
   2401         reply.getNextValueAsInt(); // fields returned, is not used
   2402         Value[] values = new Value[fieldsCount];
   2403         for (int i = 0; i < fieldsCount; i++) {
   2404             values[i] = reply.getNextValueAsValue();
   2405         }
   2406 
   2407         return values;
   2408     }
   2409 
   2410     /**
   2411      * Returns the value of one or more static fields of the reference type
   2412      *
   2413      * @param refTypeID
   2414      *            The reference type ID.
   2415      * @param fieldIDs
   2416      *            IDs of fields to get
   2417      * @return An array of Value objects representing each field's value
   2418      */
   2419     public final Value[] getReferenceTypeValues(long refTypeID, long[] fieldIDs) {
   2420         int fieldsCount = fieldIDs.length;
   2421         if (fieldsCount == 0) {
   2422             return null;
   2423         }
   2424 
   2425         CommandPacket command = new CommandPacket(
   2426                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
   2427                 JDWPCommands.ReferenceTypeCommandSet.GetValuesCommand);
   2428         command.setNextValueAsReferenceTypeID(refTypeID);
   2429         command.setNextValueAsInt(fieldsCount);
   2430         for (int i = 0; i < fieldsCount; i++) {
   2431             command.setNextValueAsFieldID(fieldIDs[i]);
   2432         }
   2433 
   2434         ReplyPacket reply = checkReply(performCommand(command));
   2435         reply.getNextValueAsInt(); // fields returned, is not used
   2436         Value[] values = new Value[fieldsCount];
   2437         for (int i = 0; i < fieldsCount; i++) {
   2438             values[i] = reply.getNextValueAsValue();
   2439         }
   2440 
   2441         return values;
   2442     }
   2443 
   2444     /**
   2445      * Returns the value of one static field of the reference type
   2446      *
   2447      * @param refTypeID
   2448      *            The reference type ID.
   2449      * @param fieldID
   2450      *            ID of field to get
   2451      * @return A Value object representing the field's value
   2452      */
   2453     public final Value getReferenceTypeValue(long refTypeID, long fieldID) {
   2454         Value[] values = getReferenceTypeValues(refTypeID, new long[]{fieldID});
   2455         return values[0];
   2456     }
   2457 
   2458     /**
   2459      * Returns the value of the 'this' reference for this frame
   2460      *
   2461      * @param threadID
   2462      *            The frame's thread ID
   2463      * @param frameID
   2464      *            The frame ID.
   2465      * @return The 'this' object ID for this frame.
   2466      */
   2467     public final long getThisObject(long threadID, long frameID) {
   2468         CommandPacket command = new CommandPacket(
   2469                 JDWPCommands.StackFrameCommandSet.CommandSetID,
   2470                 JDWPCommands.StackFrameCommandSet.ThisObjectCommand);
   2471         command.setNextValueAsThreadID(threadID);
   2472         command.setNextValueAsFrameID(frameID);
   2473         ReplyPacket reply = checkReply(performCommand(command));
   2474         TaggedObject taggedObject = reply.getNextValueAsTaggedObject();
   2475         return taggedObject.objectID;
   2476     }
   2477 
   2478     /**
   2479      * Returns information for each field in a reference type including
   2480      * inherited fields
   2481      *
   2482      * @param classID
   2483      *            The reference type ID
   2484      * @return A list of Field objects representing each field of the class
   2485      */
   2486     public final List getAllFields(long classID) {
   2487         ArrayList<Field> fields = new ArrayList<Field>(0);
   2488 
   2489         long superID = getSuperclassId(classID);
   2490         if (superID != 0) {
   2491             List superClassFields = getAllFields(superID);
   2492             for (int i = 0; i < superClassFields.size(); i++) {
   2493                 fields.add((Field) superClassFields.toArray()[i]);
   2494             }
   2495         }
   2496 
   2497         ReplyPacket reply = getFieldsInClass(classID);
   2498         int fieldsCount = reply.getNextValueAsInt();
   2499         for (int i = 0; i < fieldsCount; i++) {
   2500             Field field = new Field(reply.getNextValueAsFieldID(), classID,
   2501                     reply.getNextValueAsString(), reply.getNextValueAsString(),
   2502                     reply.getNextValueAsInt());
   2503             fields.add(field);
   2504         }
   2505 
   2506         return fields;
   2507     }
   2508 
   2509     /**
   2510      * Returns the reference type reflected by this class object
   2511      *
   2512      * @param classObjectID
   2513      *            The class object ID.
   2514      * @return ReplyPacket for corresponding command
   2515      */
   2516     public final ReplyPacket getReflectedType(long classObjectID) {
   2517         CommandPacket command = new CommandPacket(
   2518                 JDWPCommands.ClassObjectReferenceCommandSet.CommandSetID,
   2519                 JDWPCommands.ClassObjectReferenceCommandSet.ReflectedTypeCommand);
   2520         command.setNextValueAsClassObjectID(classObjectID);
   2521         return checkReply(performCommand(command));
   2522     }
   2523 
   2524     /**
   2525      * Returns the JNI signature of a reference type. JNI signature formats are
   2526      * described in the Java Native Interface Specification
   2527      *
   2528      * @param refTypeID
   2529      *            The reference type ID.
   2530      * @return The JNI signature for the reference type.
   2531      */
   2532     public final String getReferenceTypeSignature(long refTypeID) {
   2533         CommandPacket command = new CommandPacket(
   2534                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
   2535                 JDWPCommands.ReferenceTypeCommandSet.SignatureCommand);
   2536         command.setNextValueAsReferenceTypeID(refTypeID);
   2537         ReplyPacket reply = checkReply(performCommand(command));
   2538         return reply.getNextValueAsString();
   2539     }
   2540 
   2541     /**
   2542      * Returns the thread group that contains a given thread
   2543      *
   2544      * @param threadID
   2545      *            The thread object ID.
   2546      * @return The thread group ID of this thread.
   2547      */
   2548     public final long getThreadGroupID(long threadID) {
   2549         CommandPacket command = new CommandPacket(
   2550                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
   2551                 JDWPCommands.ThreadReferenceCommandSet.ThreadGroupCommand);
   2552         command.setNextValueAsThreadID(threadID);
   2553         ReplyPacket reply = checkReply(performCommand(command));
   2554         return reply.getNextValueAsThreadGroupID();
   2555     }
   2556 
   2557     /**
   2558      * Checks whether a given thread is suspended or not
   2559      *
   2560      * @param threadID
   2561      *            The thread object ID.
   2562      * @return True if a given thread is suspended, false otherwise.
   2563      */
   2564     public final boolean isThreadSuspended(long threadID) {
   2565         CommandPacket command = new CommandPacket(
   2566                 JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
   2567                 JDWPCommands.ThreadReferenceCommandSet.StatusCommand);
   2568         command.setNextValueAsThreadID(threadID);
   2569         ReplyPacket reply = checkReply(performCommand(command));
   2570         reply.getNextValueAsInt(); // the thread's status; is not used
   2571         return reply.getNextValueAsInt() == JDWPConstants.SuspendStatus.SUSPEND_STATUS_SUSPENDED;
   2572     }
   2573 
   2574     /**
   2575      * Returns JNI signature of method.
   2576      *
   2577      * @param classID
   2578      *            The reference type ID.
   2579      * @param methodID
   2580      *            The method ID.
   2581      * @return JNI signature of method.
   2582      */
   2583     public final String getMethodSignature(long classID, long methodID) {
   2584         CommandPacket command = new CommandPacket(
   2585                 JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
   2586                 JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
   2587         command.setNextValueAsReferenceTypeID(classID);
   2588         ReplyPacket reply = checkReply(performCommand(command));
   2589         int methods = reply.getNextValueAsInt();
   2590         String value = null;
   2591         for (int i = 0; i < methods; i++) {
   2592             long mID = reply.getNextValueAsMethodID();
   2593             reply.getNextValueAsString(); // name of the method; is not used
   2594             String methodSign = reply.getNextValueAsString();
   2595             reply.getNextValueAsInt();
   2596             if (mID == methodID) {
   2597                 value = methodSign;
   2598                 value = value.replaceAll("/", ".");
   2599                 int lastRoundBracketIndex = value.lastIndexOf(")");
   2600                 value = value.substring(0, lastRoundBracketIndex + 1);
   2601                 break;
   2602             }
   2603         }
   2604 
   2605         return value;
   2606     }
   2607 
   2608     /**
   2609      * Returns the characters contained in the string
   2610      *
   2611      * @param objectID
   2612      *            The String object ID.
   2613      * @return A string value.
   2614      */
   2615     public final String getStringValue(long objectID) {
   2616         CommandPacket command = new CommandPacket(
   2617                 JDWPCommands.StringReferenceCommandSet.CommandSetID,
   2618                 JDWPCommands.StringReferenceCommandSet.ValueCommand);
   2619         command.setNextValueAsObjectID(objectID);
   2620         ReplyPacket reply = checkReply(performCommand(command));
   2621         return reply.getNextValueAsString();
   2622     }
   2623 
   2624     /**
   2625      * Returns a range of array components
   2626      *
   2627      * @param objectID
   2628      *            The array object ID.
   2629      * @return The retrieved values.
   2630      */
   2631     public Value[] getArrayValues(long objectID) {
   2632         CommandPacket command = new CommandPacket(
   2633                 JDWPCommands.ArrayReferenceCommandSet.CommandSetID,
   2634                 JDWPCommands.ArrayReferenceCommandSet.LengthCommand);
   2635         command.setNextValueAsArrayID(objectID);
   2636         ReplyPacket reply = checkReply(performCommand(command));
   2637         int length = reply.getNextValueAsInt();
   2638 
   2639         if (length == 0) {
   2640             return null;
   2641         }
   2642 
   2643         command = new CommandPacket(
   2644                 JDWPCommands.ArrayReferenceCommandSet.CommandSetID,
   2645                 JDWPCommands.ArrayReferenceCommandSet.GetValuesCommand);
   2646         command.setNextValueAsArrayID(objectID);
   2647         command.setNextValueAsInt(0);
   2648         command.setNextValueAsInt(length);
   2649         reply = checkReply(performCommand(command));
   2650         ArrayRegion arrayRegion = reply.getNextValueAsArrayRegion();
   2651 
   2652         Value[] values = new Value[length];
   2653         for (int i = 0; i < length; i++) {
   2654             values[i] = arrayRegion.getValue(i);
   2655         }
   2656 
   2657         return values;
   2658     }
   2659 
   2660     /**
   2661      * Returns a source line number according to a corresponding line code index
   2662      * in a method's line table.
   2663      *
   2664      * @param classID
   2665      *            The class object ID.
   2666      * @param methodID
   2667      *            The method ID.
   2668      * @param codeIndex
   2669      *            The line code index.
   2670      * @return An integer line number.
   2671      */
   2672     public final int getLineNumber(long classID, long methodID, long codeIndex) {
   2673         int lineNumber = -1;
   2674         ReplyPacket reply = getLineTable(classID, methodID);
   2675         if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
   2676             return lineNumber;
   2677         }
   2678 
   2679         reply.getNextValueAsLong(); // start line index, is not used
   2680         reply.getNextValueAsLong(); // end line index, is not used
   2681         int lines = reply.getNextValueAsInt();
   2682         for (int i = 0; i < lines; i++) {
   2683             long lineCodeIndex = reply.getNextValueAsLong();
   2684             lineNumber = reply.getNextValueAsInt();
   2685             if (lineCodeIndex == codeIndex) {
   2686                 break;
   2687             }
   2688 
   2689             if (lineCodeIndex > codeIndex) {
   2690                 --lineNumber;
   2691                 break;
   2692             }
   2693         }
   2694 
   2695         return lineNumber;
   2696     }
   2697 
   2698     /**
   2699      * Returns a line code index according to a corresponding line number in a
   2700      * method's line table.
   2701      *
   2702      * @param classID
   2703      *            The class object ID.
   2704      * @param methodID
   2705      *            The method ID.
   2706      * @param lineNumber
   2707      *            A source line number.
   2708      * @return An integer representing the line code index.
   2709      */
   2710     public final long getLineCodeIndex(long classID, long methodID,
   2711             int lineNumber) {
   2712         ReplyPacket reply = getLineTable(classID, methodID);
   2713         if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
   2714             return -1L;
   2715         }
   2716 
   2717         reply.getNextValueAsLong(); // start line index, is not used
   2718         reply.getNextValueAsLong(); // end line index, is not used
   2719         int lines = reply.getNextValueAsInt();
   2720         for (int i = 0; i < lines; i++) {
   2721             long lineCodeIndex = reply.getNextValueAsLong();
   2722             if (lineNumber == reply.getNextValueAsInt()) {
   2723                 return lineCodeIndex;
   2724             }
   2725         }
   2726 
   2727         return -1L;
   2728     }
   2729 
   2730     /**
   2731      * Returns all variables which are visible within the given frame.
   2732      *
   2733      * @param frame
   2734      *            The frame whose visible local variables to retrieve.
   2735      * @return A list of Variable objects representing each visible local
   2736      *         variable within the given frame.
   2737      */
   2738     public final List getLocalVars(Frame frame) {
   2739         List vars = getVariableTable(frame.getLocation().classID, frame
   2740                 .getLocation().methodID);
   2741         if (vars == null) {
   2742             return null;
   2743         }
   2744 
   2745         // All variables that are not visible from within current frame must be
   2746         // removed from the list
   2747         long frameCodeIndex = frame.getLocation().index;
   2748         for (int i = 0; i < vars.size(); i++) {
   2749             Variable var = (Variable) vars.toArray()[i];
   2750             long varCodeIndex = var.getCodeIndex();
   2751             if (varCodeIndex > frameCodeIndex
   2752                     || (frameCodeIndex >= varCodeIndex + var.getLength())) {
   2753                 vars.remove(i);
   2754                 --i;
   2755                 continue;
   2756             }
   2757         }
   2758 
   2759         return vars;
   2760     }
   2761 
   2762     /**
   2763      * Sets the value of one or more local variables
   2764      *
   2765      * @param frame
   2766      *            The frame ID.
   2767      * @param vars
   2768      *            An array of Variable objects whose values to set
   2769      * @param values
   2770      *            An array of Value objects to set
   2771      */
   2772     public final void setLocalVars(Frame frame, Variable[] vars, Value[] values) {
   2773         if (vars.length != values.length) {
   2774             throw new TestErrorException(
   2775                     "Number of variables doesn't correspond to number of their values");
   2776         }
   2777 
   2778         CommandPacket command = new CommandPacket(
   2779                 JDWPCommands.StackFrameCommandSet.CommandSetID,
   2780                 JDWPCommands.StackFrameCommandSet.SetValuesCommand);
   2781         command.setNextValueAsThreadID(frame.getThreadID());
   2782         command.setNextValueAsFrameID(frame.getID());
   2783         command.setNextValueAsInt(vars.length);
   2784         for (int i = 0; i < vars.length; i++) {
   2785             command.setNextValueAsInt(vars[i].getSlot());
   2786             command.setNextValueAsValue(values[i]);
   2787         }
   2788 
   2789         checkReply(performCommand(command));
   2790     }
   2791 
   2792     /**
   2793      * Sets the value of one or more instance fields
   2794      *
   2795      * @param objectID
   2796      *            The object ID.
   2797      * @param fieldIDs
   2798      *            An array of fields IDs
   2799      * @param values
   2800      *            An array of Value objects representing each value to set
   2801      */
   2802     public final void setInstanceFieldsValues(long objectID, long[] fieldIDs,
   2803             Value[] values) {
   2804         if (fieldIDs.length != values.length) {
   2805             throw new TestErrorException(
   2806                     "Number of fields doesn't correspond to number of their values");
   2807         }
   2808 
   2809         CommandPacket command = new CommandPacket(
   2810                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
   2811                 JDWPCommands.ObjectReferenceCommandSet.SetValuesCommand);
   2812         command.setNextValueAsObjectID(objectID);
   2813         command.setNextValueAsInt(fieldIDs.length);
   2814         for (int i = 0; i < fieldIDs.length; i++) {
   2815             command.setNextValueAsFieldID(fieldIDs[i]);
   2816             command.setNextValueAsUntaggedValue(values[i]);
   2817         }
   2818 
   2819         checkReply(performCommand(command));
   2820     }
   2821 
   2822     /**
   2823      * Sets a range of array components. The specified range must be within the
   2824      * bounds of the array.
   2825      *
   2826      * @param arrayID
   2827      *            The array object ID.
   2828      * @param firstIndex
   2829      *            The first index to set.
   2830      * @param values
   2831      *            An array of Value objects representing each value to set.
   2832      */
   2833     public final void setArrayValues(long arrayID, int firstIndex,
   2834             Value[] values) {
   2835         CommandPacket command = new CommandPacket(
   2836                 JDWPCommands.ArrayReferenceCommandSet.CommandSetID,
   2837                 JDWPCommands.ArrayReferenceCommandSet.SetValuesCommand);
   2838         command.setNextValueAsArrayID(arrayID);
   2839         command.setNextValueAsInt(firstIndex);
   2840         command.setNextValueAsInt(values.length);
   2841         for (int i = 0; i < values.length; i++) {
   2842             command.setNextValueAsUntaggedValue(values[i]);
   2843         }
   2844 
   2845         checkReply(performCommand(command));
   2846     }
   2847 
   2848     /**
   2849      * Sets the value of one or more static fields
   2850      *
   2851      * @param classID
   2852      *            The class type ID.
   2853      * @param fieldIDs
   2854      *            An array of fields IDs
   2855      * @param values
   2856      *            An array of Value objects representing each value to set
   2857      */
   2858     public final void setStaticFieldsValues(long classID, long[] fieldIDs,
   2859             Value[] values) {
   2860         if (fieldIDs.length != values.length) {
   2861             throw new TestErrorException(
   2862                     "Number of fields doesn't correspond to number of their values");
   2863         }
   2864 
   2865         CommandPacket command = new CommandPacket(
   2866                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
   2867                 JDWPCommands.ClassTypeCommandSet.SetValuesCommand);
   2868         command.setNextValueAsClassID(classID);
   2869         command.setNextValueAsInt(fieldIDs.length);
   2870         for (int i = 0; i < fieldIDs.length; i++) {
   2871             command.setNextValueAsFieldID(fieldIDs[i]);
   2872             command.setNextValueAsUntaggedValue(values[i]);
   2873         }
   2874 
   2875         checkReply(performCommand(command));
   2876     }
   2877 
   2878     /**
   2879      * Creates java String in target VM with the given value.
   2880      *
   2881      * @param value
   2882      *            The value of the string.
   2883      * @return The string id.
   2884      */
   2885     public final long createString(String value) {
   2886         CommandPacket command = new CommandPacket(
   2887                 JDWPCommands.VirtualMachineCommandSet.CommandSetID,
   2888                 JDWPCommands.VirtualMachineCommandSet.CreateStringCommand);
   2889         command.setNextValueAsString(value);
   2890         ReplyPacket reply = checkReply(performCommand(command));
   2891         return reply.getNextValueAsStringID();
   2892     }
   2893 
   2894     /**
   2895      * Processes JDWP PopFrames command from StackFrame command set.
   2896      *
   2897      * @param frame
   2898      *            The instance of Frame.
   2899      */
   2900     public final void popFrame(Frame frame) {
   2901         CommandPacket command = new CommandPacket(
   2902                 JDWPCommands.StackFrameCommandSet.CommandSetID,
   2903                 JDWPCommands.StackFrameCommandSet.PopFramesCommand);
   2904         command.setNextValueAsThreadID(frame.getThreadID());
   2905         command.setNextValueAsFrameID(frame.getID());
   2906         checkReply(performCommand(command));
   2907     }
   2908 
   2909     /**
   2910      * Invokes a member method of the given object.
   2911      *
   2912      * @param objectID
   2913      *            The object ID.
   2914      * @param threadID
   2915      *            The thread ID.
   2916      * @param methodName
   2917      *            The name of method for the invocation.
   2918      * @param args
   2919      *            The arguments for the invocation.
   2920      * @param options
   2921      *            The invocation options.
   2922      * @return ReplyPacket for corresponding command
   2923      */
   2924     public final ReplyPacket invokeInstanceMethod(long objectID, long threadID,
   2925             String methodName, Value[] args, int options) {
   2926         long classID = getReferenceType(objectID);
   2927         long methodID = getMethodID(classID, methodName);
   2928         CommandPacket command = new CommandPacket(
   2929                 JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
   2930                 JDWPCommands.ObjectReferenceCommandSet.InvokeMethodCommand);
   2931         command.setNextValueAsObjectID(objectID);
   2932         command.setNextValueAsThreadID(threadID);
   2933         command.setNextValueAsClassID(classID);
   2934         command.setNextValueAsMethodID(methodID);
   2935         command.setNextValueAsInt(args.length);
   2936         for (int i = 0; i < args.length; i++) {
   2937             command.setNextValueAsValue(args[i]);
   2938         }
   2939         command.setNextValueAsInt(options);
   2940 
   2941         return checkReply(performCommand(command));
   2942     }
   2943 
   2944     /**
   2945      * Invokes a static method of the given class.
   2946      *
   2947      * @param classID
   2948      *            The class type ID.
   2949      * @param threadID
   2950      *            The thread ID.
   2951      * @param methodName
   2952      *            The name of method for the invocation.
   2953      * @param args
   2954      *            The arguments for the invocation.
   2955      * @param options
   2956      *            The invocation options.
   2957      * @return ReplyPacket for corresponding command
   2958      */
   2959     public final ReplyPacket invokeStaticMethod(long classID, long threadID,
   2960             String methodName, Value[] args, int options) {
   2961         long methodID = getMethodID(classID, methodName);
   2962         CommandPacket command = new CommandPacket(
   2963                 JDWPCommands.ClassTypeCommandSet.CommandSetID,
   2964                 JDWPCommands.ClassTypeCommandSet.InvokeMethodCommand);
   2965         command.setNextValueAsClassID(classID);
   2966         command.setNextValueAsThreadID(threadID);
   2967         command.setNextValueAsMethodID(methodID);
   2968         command.setNextValueAsInt(args.length);
   2969         for (int i = 0; i < args.length; i++) {
   2970             command.setNextValueAsValue(args[i]);
   2971         }
   2972         command.setNextValueAsInt(options);
   2973 
   2974         return checkReply(performCommand(command));
   2975     }
   2976 }
   2977