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

package com.sun.jdi;

import com.sun.jdi.event.EventQueue;
import com.sun.jdi.request.EventRequestManager;

import java.util.List;
import java.util.Map;

/**
 * A virtual machine targeted for debugging.
 * More precisely, a {@link Mirror mirror} representing the
 * composite state of the target VM.
 * All other mirrors are associated with an instance of this
 * interface.  Access to all other mirrors is achieved
 * directly or indirectly through an instance of this
 * interface.
 * Access to global VM properties and control of VM execution
 * are supported directly by this interface.
 * <P>
 * Instances of this interface are created by instances of
 * {@link com.sun.jdi.connect.Connector}. For example,
 * an {@link com.sun.jdi.connect.AttachingConnector AttachingConnector}
 * attaches to a target VM and returns its virtual machine mirror.
 * A Connector will typically create a VirtualMachine by invoking
 * the VirtualMachineManager's {@link
 * com.sun.jdi.VirtualMachineManager#createVirtualMachine(Connection)}
 * createVirtualMachine(Connection) method.
 * <p>
 * Note that a target VM launched by a launching connector is not
 * guaranteed to be stable until after the {@link com.sun.jdi.event.VMStartEvent} has been
 * received.
 * <p>
 * Any method on <code>VirtualMachine</code> which
 * takes <code>VirtualMachine</code> as an parameter may throw
 * {@link com.sun.jdi.VMDisconnectedException} if the target VM is
 * disconnected and the {@link com.sun.jdi.event.VMDisconnectEvent} has been or is
 * available to be read from the {@link com.sun.jdi.event.EventQueue}.
 * <p>
 * Any method on <code>VirtualMachine</code> which
 * takes <code>VirtualMachine</code> as an parameter may throw
 * {@link com.sun.jdi.VMOutOfMemoryException} if the target VM has run out of memory.
 *
 * @author Robert Field
 * @author Gordon Hirsch
 * @author James McIlree
 * @since  1.3
 */
public interface VirtualMachine extends Mirror {

    /**
     * Returns the loaded reference types that
     * match a given name. The name must be fully qualified
     * (for example, java.lang.String). The returned list
     * will contain a {@link ReferenceType} for each class
     * or interface found with the given name. The search
     * is confined to loaded classes only; no attempt is made
     * to load a class of the given name.
     * <P>
     * The returned list will include reference types
     * loaded at least to the point of preparation and
     * types (like array) for which preparation is
     * not defined.
     *
     * @param className the class/interface name to search for
     * @return a list of {@link ReferenceType} objects, each
     * mirroring a type in the target VM with the given name.
     */
    List<ReferenceType> classesByName(String className);

    /**
     * Returns all loaded types. For each loaded type in the target
     * VM a {@link ReferenceType} will be placed in the returned list.
     * The list will include ReferenceTypes which mirror classes,
     * interfaces, and array types.
     * <P>
     * The returned list will include reference types
     * loaded at least to the point of preparation and
     * types (like array) for which preparation is
     * not defined.
     *
     * @return a list of {@link ReferenceType} objects, each mirroring
     * a loaded type in the target VM.
     */
    List<ReferenceType> allClasses();

    /**
     * All classes given are redefined according to the
     * definitions supplied.  A method in a redefined class
     * is called 'equivalent' (to the old version of the
     * method) if
     * <UL>
     * <LI>their bytecodes are the same except for indicies into
     *   the constant pool, and
     * <LI>the referenced constants are equal.
     * </UL>
     * Otherwise, the new method is called 'non-equivalent'.
     * If a redefined method has active stack frames, those active
     * frames continue to run the bytecodes of the previous version of the
     * method.  If the new version of such a method is non-equivalent,
     * then a method from one of these active frames is called 'obsolete' and
     * {@link Method#isObsolete Method.isObsolete()}
     * will return true when called on one of these methods.
     * If resetting such a frame is desired, use
     * {@link ThreadReference#popFrames ThreadReference.popFrames(StackFrame)}
     * to pop the old obsolete method execution from the stack.
     * New invocations of redefined methods will always invoke the new versions.
     * <p>
     * This function does not cause any initialization except
     * that which would occur under the customary JVM semantics.
     * In other words, redefining a class does not cause
     * its initializers to be run. The values of preexisting
     * static variables will remain as they were prior to the
     * call. However, completely uninitialized (new) static
     * variables will be assigned their default value.
     * <p>
     * If a redefined class has instances then all those
     * instances will have the fields defined by the redefined
     * class at the completion of the call. Preexisting fields
     * will retain their previous values. Any new fields will
     * have their default values; no instance initializers or
     * constructors are run.
     * <p>
     * Threads need not be suspended.
     * <p>
     * No events are generated by this function.
     * <p>
     * All breakpoints in the redefined classes are deleted.
     * <p>
     * Not all target virtual machines support this operation.
     * Use {@link #canRedefineClasses() canRedefineClasses()}
     * to determine if the operation is supported.
     * Use {@link #canAddMethod() canAddMethod()}
     * to determine if the redefinition can add methods.
     * Use {@link #canUnrestrictedlyRedefineClasses() canUnrestrictedlyRedefineClasses()}
     * to determine if the redefinition can change the schema,
     * delete methods, change the class hierarchy, etc.
     *
     * @param classToBytes A map from {@link ReferenceType}
     * to array of byte.
     * The bytes represent the new class definition and
     * are in Java Virtual Machine class file format.
     *
     * @throws java.lang.UnsupportedOperationException if
     * the target virtual machine does not support this
     * operation.
     * <UL>
     * <LI>If {@link #canRedefineClasses() canRedefineClasses()}
     * is false any call of this method will throw this exception.
     * <LI>If {@link #canAddMethod() canAddMethod()} is false
     * attempting to add a method will throw this exception.
     * <LI>If {@link #canUnrestrictedlyRedefineClasses()
     *            canUnrestrictedlyRedefineClasses()}
     * is false, attempting any of the following will throw
     * this exception
     *   <UL>
     *   <LI>changing the schema (the fields)
     *   <LI>changing the hierarchy (subclasses, interfaces)
     *   <LI>deleting a method
     *   <LI>changing class modifiers
     *   <LI>changing method modifiers
     *   </UL>
     * </UL>
     *
     * @throws java.lang.NoClassDefFoundError if the bytes
     * don't correspond to the reference type (the names
     * don't match).
     *
     * @throws java.lang.VerifyError if a "verifier" detects
     * that a class, though well formed, contains an internal
     * inconsistency or security problem.
     *
     * @throws java.lang.ClassFormatError if the bytes
     * do not represent a valid class.
     *
     * @throws java.lang.ClassCircularityError if a
     * circularity has been detected while initializing a class.
     *
     * @throws java.lang.UnsupportedClassVersionError if the
     * major and minor version numbers in bytes
     * are not supported by the VM.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     *
     * @see Method#isObsolete
     * @see ThreadReference#popFrames
     * @see #canRedefineClasses
     * @see #canAddMethod
     * @see #canUnrestrictedlyRedefineClasses
     *
     * @since 1.4
     */
    void redefineClasses(Map<? extends ReferenceType,byte[]> classToBytes);

    /**
     * Returns a list of the currently running threads. For each
     * running thread in the target VM, a {@link ThreadReference}
     * that mirrors it is placed in the list.
     * The returned list contains threads created through
     * java.lang.Thread, all native threads attached to
     * the target VM through JNI, and system threads created
     * by the target VM. Thread objects that have
     * not yet been started
     * (see {@link java.lang.Thread#start Thread.start()})
     * and thread objects that have
     * completed their execution are not included in the returned list.
     *
     * @return a list of {@link ThreadReference} objects, one for each
     * running thread in the mirrored VM.
     */
    List<ThreadReference> allThreads();

    /**
     * Suspends the execution of the application running in this
     * virtual machine. All threads currently running will be suspended.
     * <p>
     * Unlike {@link java.lang.Thread#suspend Thread.suspend()},
     * suspends of both the virtual machine and individual threads are
     * counted. Before a thread will run again, it must be resumed
     * (through {@link #resume} or {@link ThreadReference#resume})
     * the same number of times it has been suspended.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     */
    void suspend();

    /**
     * Continues the execution of the application running in this
     * virtual machine. All threads are resumed as documented in
     * {@link ThreadReference#resume}.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     *
     * @see #suspend
     */
    void resume();

    /**
     * Returns each thread group which does not have a parent. For each
     * top level thread group a {@link ThreadGroupReference} is placed in the
     * returned list.
     * <p>
     * This command may be used as the first step in building a tree
     * (or trees) of the existing thread groups.
     *
     * @return a list of {@link ThreadGroupReference} objects, one for each
     * top level thread group.
     */
    List<ThreadGroupReference> topLevelThreadGroups();

    /**
     * Returns the event queue for this virtual machine.
     * A virtual machine has only one {@link EventQueue} object, this
     * method will return the same instance each time it
     * is invoked.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     *
     * @return the {@link EventQueue} for this virtual machine.
     */
    EventQueue eventQueue();

    /**
     * Returns the event request manager for this virtual machine.
     * The {@link EventRequestManager} controls user settable events
     * such as breakpoints.
     * A virtual machine has only one {@link EventRequestManager} object,
     * this method will return the same instance each time it
     * is invoked.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     *
     * @return the {@link EventRequestManager} for this virtual machine.
     */
    EventRequestManager eventRequestManager();

    /**
     * Creates a {@link BooleanValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a boolean for which to create the value
     * @return the {@link BooleanValue} for the given boolean.
     */
    BooleanValue mirrorOf(boolean value);

    /**
     * Creates a {@link ByteValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a byte for which to create the value
     * @return the {@link ByteValue} for the given byte.
     */
    ByteValue mirrorOf(byte value);

    /**
     * Creates a {@link CharValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a char for which to create the value
     * @return the {@link CharValue} for the given char.
     */
    CharValue mirrorOf(char value);

    /**
     * Creates a {@link ShortValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a short for which to create the value
     * @return the {@link ShortValue} for the given short.
     */
    ShortValue mirrorOf(short value);

    /**
     * Creates an {@link IntegerValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value an int for which to create the value
     * @return the {@link IntegerValue} for the given int.
     */
    IntegerValue mirrorOf(int value);

    /**
     * Creates a {@link LongValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a long for which to create the value
     * @return the {@link LongValue} for the given long.
     */
    LongValue mirrorOf(long value);

    /**
     * Creates a {@link FloatValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a float for which to create the value
     * @return the {@link FloatValue} for the given float.
     */
    FloatValue mirrorOf(float value);

    /**
     * Creates a {@link DoubleValue} for the given value. This value
     * can be used for setting and comparing against a value retrieved
     * from a variable or field in this virtual machine.
     *
     * @param value a double for which to create the value
     * @return the {@link DoubleValue} for the given double.
     */
    DoubleValue mirrorOf(double value);

    /**
     * Creates a string in this virtual machine.
     * The created string can be used for setting and comparing against
     * a string value retrieved from a variable or field in this
     * virtual machine.
     *
     * @param value the string to be created
     * @return a {@link StringReference} that mirrors the newly created
     * string in the target VM.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only
     * -see {@link VirtualMachine#canBeModified()}.
     */
    StringReference mirrorOf(String value);


    /**
     * Creates a {@link VoidValue}.  This value
     * can be passed to {@link ThreadReference#forceEarlyReturn}
     * when a void method is to be exited.
     *
     * @return the {@link VoidValue}.
     */
    VoidValue mirrorOfVoid();

    /**
     * Returns the {@link java.lang.Process} object for this
     * virtual machine if launched
     * by a {@link com.sun.jdi.connect.LaunchingConnector}
     *
     * @return the {@link java.lang.Process} object for this virtual
     * machine, or null if it was not launched by a
     * {@link com.sun.jdi.connect.LaunchingConnector}.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only
     * -see {@link VirtualMachine#canBeModified()}.
     */
    Process process();

    /**
     * Invalidates this virtual machine mirror.
     * The communication channel to the target VM is closed, and
     * the target VM prepares to accept another subsequent connection
     * from this debugger or another debugger, including the
     * following tasks:
     * <ul>
     * <li>All event requests are cancelled.
     * <li>All threads suspended by {@link #suspend} or by
     * {@link ThreadReference#suspend} are resumed as many
     * times as necessary for them to run.
     * <li>Garbage collection is re-enabled in all cases where it was
     * disabled through {@link ObjectReference#disableCollection}.
     * </ul>
     * Any current method invocations executing in the target VM
     * are continued after the disconnection. Upon completion of any such
     * method invocation, the invoking thread continues from the
     * location where it was originally stopped.
     * <p>
     * Resources originating in
     * this VirtualMachine (ObjectReferences, ReferenceTypes, etc.)
     * will become invalid.
     */
    void dispose();

    /**
     * Causes the mirrored VM to terminate with the given error code.
     * All resources associated with this VirtualMachine are freed.
     * If the mirrored VM is remote, the communication channel
     * to it will be closed. Resources originating in
     * this VirtualMachine (ObjectReferences, ReferenceTypes, etc.)
     * will become invalid.
     * <p>
     * Threads running in the mirrored VM are abruptly terminated.
     * A thread death exception is not thrown and
     * finally blocks are not run.
     *
     * @param exitCode the exit code for the target VM.  On some platforms,
     * the exit code might be truncated, for example, to the lower order 8 bits.
     *
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     */
    void exit(int exitCode);

    /**
     * Determines if the target VM supports watchpoints
     * for field modification.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canWatchFieldModification();

    /**
     * Determines if the target VM supports watchpoints
     * for field access.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canWatchFieldAccess();

    /**
     * Determines if the target VM supports the retrieval
     * of a method's bytecodes.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canGetBytecodes();

    /**
     * Determines if the target VM supports the query
     * of the synthetic attribute of a method or field.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canGetSyntheticAttribute();

    /**
     * Determines if the target VM supports the retrieval
     * of the monitors owned by a thread.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canGetOwnedMonitorInfo();

    /**
     * Determines if the target VM supports the retrieval
     * of the monitor for which a thread is currently waiting.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canGetCurrentContendedMonitor();

    /**
     * Determines if the target VM supports the retrieval
     * of the monitor information for an object.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canGetMonitorInfo();

    /**
     * Determines if the target VM supports filtering
     * events by specific instance object.  For example,
     * see {@link com.sun.jdi.request.BreakpointRequest#addInstanceFilter}.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     */
    boolean canUseInstanceFilters();

    /**
     * Determines if the target VM supports any level
     * of class redefinition.
     * @see #redefineClasses
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canRedefineClasses();

    /**
     * Determines if the target VM supports the addition
     * of methods when performing class redefinition.
     * @see #redefineClasses
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canAddMethod();

    /**
     * Determines if the target VM supports unrestricted
     * changes when performing class redefinition.
     * @see #redefineClasses
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canUnrestrictedlyRedefineClasses();

    /**
     * Determines if the target VM supports popping
     * frames of a threads stack.
     * @see ThreadReference#popFrames
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canPopFrames();

    /**
     * Determines if the target VM supports getting
     * the source debug extension.
     * @see ReferenceType#sourceDebugExtension
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canGetSourceDebugExtension();

    /**
     * Determines if the target VM supports the creation of
     * {@link com.sun.jdi.request.VMDeathRequest}s.
     * @see com.sun.jdi.request.EventRequestManager#createVMDeathRequest
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.4
     */
    boolean canRequestVMDeathEvent();

    /**
     * Determines if the target VM supports the inclusion of return values
     * in
     * {@link com.sun.jdi.event.MethodExitEvent}s.
     * @see com.sun.jdi.request.EventRequestManager#createMethodExitRequest
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canGetMethodReturnValues();

    /**
     * Determines if the target VM supports the accessing of class instances,
     * instance counts, and referring objects.
     *
     * @see #instanceCounts
     * @see ReferenceType#instances(long)
     * @see ObjectReference#referringObjects(long)
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canGetInstanceInfo();


    /**
     * Determines if the target VM supports the filtering of
     * class prepare events by source name.
     *
     * see {@link com.sun.jdi.request.ClassPrepareRequest#addSourceNameFilter}.
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canUseSourceNameFilters();

    /**
     * Determines if the target VM supports the forcing of a method to
     * return early.
     *
     * @see ThreadReference#forceEarlyReturn(Value)
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canForceEarlyReturn();

    /**
     * Determines if the target VM is a read-only VM.  If a method which
     * would modify the state of the VM is called on a read-only VM,
     * then {@link VMCannotBeModifiedException} is thrown.
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.5
     */

    boolean canBeModified();

    /**
     * Determines if the target VM supports the creation of
     * {@link com.sun.jdi.request.MonitorContendedEnterRequest}s.
     * {@link com.sun.jdi.request.MonitorContendedEnteredRequest}s.
     * {@link com.sun.jdi.request.MonitorWaitRequest}s.
     * {@link com.sun.jdi.request.MonitorWaitedRequest}s.
     * @see com.sun.jdi.request.EventRequestManager#createMonitorContendedEnterRequest
     * @see com.sun.jdi.request.EventRequestManager#createMonitorContendedEnteredRequest
     * @see com.sun.jdi.request.EventRequestManager#createMonitorWaitRequest
     * @see com.sun.jdi.request.EventRequestManager#createMonitorWaitedRequest
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */

    boolean canRequestMonitorEvents();

    /**
     * Determines if the target VM supports getting which
     * frame has acquired a monitor.
     * @see com.sun.jdi.ThreadReference#ownedMonitorsAndFrames
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */

     boolean canGetMonitorFrameInfo();


    /**
     * Determines if the target VM supports reading class file
     * major and minor versions.
     *
     * @see ReferenceType#majorVersion()
     * @see ReferenceType#minorVersion()
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canGetClassFileVersion();

    /**
     * Determines if the target VM supports getting constant pool
     * information of a class.
     *
     * @see ReferenceType#constantPoolCount()
     * @see ReferenceType#constantPool()
     *
     * @return <code>true</code> if the feature is supported,
     * <code>false</code> otherwise.
     *
     * @since 1.6
     */
    boolean canGetConstantPool();

    /**
     * Set this VM's default stratum (see {@link Location} for a
     * discussion of strata).  Overrides the per-class default set
     * in the class file.
     * <P>
     * Affects location queries (such as,
     * {@link Location#sourceName()})
     * and the line boundaries used in
     * single stepping.
     *
     * @param stratum the stratum to set as VM default,
     * or null to use per-class defaults.
     *
     * @throws java.lang.UnsupportedOperationException if the
     * target virtual machine does not support this operation.
     *
     * @since 1.4
     */
    void setDefaultStratum(String stratum);

    /**
     * Return this VM's default stratum.
     *
     * @see #setDefaultStratum(String)
     * @see ReferenceType#defaultStratum()
     * @return <code>null</code> (meaning that the per-class
     * default - {@link ReferenceType#defaultStratum()} -
     * should be used) unless the default stratum has been
     * set with
     * {@link #setDefaultStratum(String)}.
     *
     * @since 1.4
     */
    String getDefaultStratum();

    /**
     * Returns the number of instances of each ReferenceType in the 'refTypes'
     * list.
     * Only instances that are reachable for the purposes of garbage collection
     * are counted.
     * <p>
     * Not all target virtual machines support this operation.
     * Use {@link VirtualMachine#canGetInstanceInfo()}
     * to determine if the operation is supported.
     *
     * @see ReferenceType#instances(long)
     * @see ObjectReference#referringObjects(long)
     * @param refTypes the list of {@link ReferenceType} objects for which counts
     *        are to be obtained.
     *
     * @return an array of <code>long</code> containing one element for each
     *         element in the 'refTypes' list.  Element i of the array contains
     *         the number of instances in the target VM of the ReferenceType at
     *         position i in the 'refTypes' list.
     *         If the 'refTypes' list is empty, a zero-length array is returned.
     *         If a ReferenceType in refTypes has been garbage collected, zero
     *         is returned for its instance count.
     * @throws java.lang.UnsupportedOperationException if
     * the target virtual machine does not support this
     * operation - see
     * {@link VirtualMachine#canGetInstanceInfo() canGetInstanceInfo()}
     * @throws NullPointerException if the 'refTypes' list is null.
     * @since 1.6
     */
    long[] instanceCounts(List<? extends ReferenceType> refTypes);

    /**
     * Returns text information on the target VM and the
     * debugger support that mirrors it. No specific format
     * for this information is guaranteed.
     * Typically, this string contains version information for the
     * target VM and debugger interfaces.
     * More precise information
     * on VM and JDI versions is available through
     * {@link #version}, {@link VirtualMachineManager#majorInterfaceVersion},
     * and {@link VirtualMachineManager#minorInterfaceVersion}
     *
     * @return the description.
     */
    String description();

    /**
     * Returns the version of the Java Runtime Environment in the target
     * VM as reported by the property <code>java.version</code>.
     * For obtaining the JDI interface version, use
     * {@link VirtualMachineManager#majorInterfaceVersion}
     * and {@link VirtualMachineManager#minorInterfaceVersion}
     *
     * @return the target VM version.
     */
    String version();

    /**
     * Returns the name of the target VM as reported by the
     * property <code>java.vm.name</code>.
     *
     * @return the target VM name.
     */
    String name();

    /** All tracing is disabled. */
    int TRACE_NONE        = 0x00000000;
    /** Tracing enabled for JDWP packets sent to target VM. */
    int TRACE_SENDS       = 0x00000001;
    /** Tracing enabled for JDWP packets received from target VM. */
    int TRACE_RECEIVES    = 0x00000002;
    /** Tracing enabled for internal event handling. */
    int TRACE_EVENTS      = 0x00000004;
    /** Tracing enabled for internal managment of reference types. */
    int TRACE_REFTYPES    = 0x00000008;
    /** Tracing enabled for internal management of object references. */
    int TRACE_OBJREFS      = 0x00000010;
    /** All tracing is enabled. */
    int TRACE_ALL         = 0x00ffffff;

    /**
     * Traces the activities performed by the com.sun.jdi implementation.
     * All trace information is output to System.err. The given trace
     * flags are used to limit the output to only the information
     * desired. The given flags are in effect and the corresponding
     * trace will continue until the next call to
     * this method.
     * <p>
     * Output is implementation dependent and trace mode may be ignored.
     *
     * @param traceFlags identifies which kinds of tracing to enable.
     */
    void setDebugTraceMode(int traceFlags);
}
