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

package com.sun.tools.example.debug.gui;

import java.io.*;
import java.util.*;

import com.sun.jdi.*;
import com.sun.jdi.request.*;

import com.sun.tools.example.debug.bdi.*;

public class CommandInterpreter {

    boolean echo;

    Environment env;

    private ContextManager context;
    private ExecutionManager runtime;
    private ClassManager classManager;
    private SourceManager sourceManager;

    private OutputSink out; //### Hack!  Should be local in each method used.
    private String lastCommand = "help";

    public CommandInterpreter(Environment env) {
        this(env, true);
    }

    public CommandInterpreter(Environment env, boolean echo) {
        this.env = env;
        this.echo = echo;
        this.runtime = env.getExecutionManager();
        this.context = env.getContextManager();
        this.classManager = env.getClassManager();
        this.sourceManager = env.getSourceManager();
    }

    private ThreadReference[] threads = null;

    /*
     * The numbering of threads is relative to the current set of threads,
     * and may be affected by the creation and termination of new threads.
     * Commands issued using such thread ids will only give reliable behavior
     * relative to what was shown earlier in 'list' commands if the VM is interrupted.
     * We need a better scheme.
     */

    private ThreadReference[] threads() throws NoSessionException {
        if (threads == null) {
            ThreadIterator ti = new ThreadIterator(getDefaultThreadGroup());
            List<ThreadReference> tlist = new ArrayList<ThreadReference>();
            while (ti.hasNext()) {
                tlist.add(ti.nextThread());
            }
            threads = (ThreadReference[])tlist.toArray(new ThreadReference[tlist.size()]);
        }
        return threads;
    }

    private ThreadReference findThread(String idToken) throws NoSessionException {
        String id;
        ThreadReference thread = null;
        if (idToken.startsWith("t@")) {
            id = idToken.substring(2);
        } else {
            id = idToken;
        }
        try {
            ThreadReference[] threads = threads();
            long threadID = Long.parseLong(id, 16);
            for (int i = 0; i < threads.length; i++) {
                if (threads[i].uniqueID() == threadID) {
                    thread = threads[i];
                    break;
                }
            }
            if (thread == null) {
                //env.failure("No thread for id \"" + idToken + "\"");
                env.failure("\"" + idToken + "\" is not a valid thread id.");
            }
        } catch (NumberFormatException e) {
            env.error("Thread id \"" + idToken + "\" is ill-formed.");
            thread = null;
        }
        return thread;
    }

    private ThreadIterator allThreads() throws NoSessionException {
        threads = null;
        //### Why not use runtime.allThreads().iterator() ?
        return new ThreadIterator(runtime.topLevelThreadGroups());
    }

    private ThreadIterator currentThreadGroupThreads() throws NoSessionException {
        threads = null;
        return new ThreadIterator(getDefaultThreadGroup());
    }

    private ThreadGroupIterator allThreadGroups() throws NoSessionException {
        threads = null;
        return new ThreadGroupIterator(runtime.topLevelThreadGroups());
    }

    private ThreadGroupReference defaultThreadGroup;

    private ThreadGroupReference getDefaultThreadGroup() throws NoSessionException {
        if (defaultThreadGroup == null) {
            defaultThreadGroup = runtime.systemThreadGroup();
        }
        return defaultThreadGroup;
    }

    private void setDefaultThreadGroup(ThreadGroupReference tg) {
        defaultThreadGroup = tg;
    }

    /*
     * Command handlers.
     */

    // Command: classes

    private void commandClasses() throws NoSessionException {
        List list = runtime.allClasses();
        OutputSink out = env.getOutputSink();
        //out.println("** classes list **");
        for (int i = 0 ; i < list.size() ; i++) {
            ReferenceType refType = (ReferenceType)list.get(i);
            out.println(refType.name());
        }
        out.show();
    }


    // Command: methods

    private void commandMethods(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("No class specified.");
            return;
        }
        String idClass = t.nextToken();
        ReferenceType cls = findClass(idClass);
        if (cls != null) {
            List methods = cls.allMethods();
            OutputSink out = env.getOutputSink();
            for (int i = 0; i < methods.size(); i++) {
                Method method = (Method)methods.get(i);
                out.print(method.declaringType().name() + " " +
                            method.name() + "(");
                Iterator it = method.argumentTypeNames().iterator();
                if (it.hasNext()) {
                    while (true) {
                        out.print((String)it.next());
                        if (!it.hasNext()) {
                            break;
                        }
                        out.print(", ");
                    }
                }
                out.println(")");
            }
            out.show();
        } else {
            //### Should validate class name syntax.
            env.failure("\"" + idClass + "\" is not a valid id or class name.");
        }
    }

    private ReferenceType findClass(String pattern) throws NoSessionException {
        List results = runtime.findClassesMatchingPattern(pattern);
        if (results.size() > 0) {
            //### Should handle multiple results sensibly.
            return (ReferenceType)results.get(0);
        }
        return null;
    }

    // Command: threads

    private void commandThreads(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            OutputSink out = env.getOutputSink();
            printThreadGroup(out, getDefaultThreadGroup(), 0);
            out.show();
            return;
        }
        String name = t.nextToken();
        ThreadGroupReference tg = findThreadGroup(name);
        if (tg == null) {
            env.failure(name + " is not a valid threadgroup name.");
        } else {
            OutputSink out = env.getOutputSink();
            printThreadGroup(out, tg, 0);
            out.show();
        }
    }

    private ThreadGroupReference findThreadGroup(String name) throws NoSessionException {
        //### Issue: Uniqueness of thread group names is not enforced.
        ThreadGroupIterator tgi = allThreadGroups();
        while (tgi.hasNext()) {
            ThreadGroupReference tg = tgi.nextThreadGroup();
            if (tg.name().equals(name)) {
                return tg;
            }
        }
        return null;
    }

    private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) {
        out.println("Group " + tg.name() + ":");
        List tlist = tg.threads();
        int maxId = 0;
        int maxName = 0;
        for (int i = 0 ; i < tlist.size() ; i++) {
            ThreadReference thr = (ThreadReference)tlist.get(i);
            int len = Utils.description(thr).length();
            if (len > maxId)
                maxId = len;
            String name = thr.name();
            int iDot = name.lastIndexOf('.');
            if (iDot >= 0 && name.length() > iDot) {
                name = name.substring(iDot + 1);
            }
            if (name.length() > maxName)
                maxName = name.length();
        }
        String maxNumString = String.valueOf(iThread + tlist.size());
        int maxNumDigits = maxNumString.length();
        for (int i = 0 ; i < tlist.size() ; i++) {
            ThreadReference thr = (ThreadReference)tlist.get(i);
            char buf[] = new char[80];
            for (int j = 0; j < 79; j++) {
                buf[j] = ' ';
            }
            buf[79] = '\0';
            StringBuffer sbOut = new StringBuffer();
            sbOut.append(buf);

            // Right-justify the thread number at start of output string
            String numString = String.valueOf(iThread + i + 1);
            sbOut.insert(maxNumDigits - numString.length(),
                         numString);
            sbOut.insert(maxNumDigits, ".");

            int iBuf = maxNumDigits + 2;
            sbOut.insert(iBuf, Utils.description(thr));
            iBuf += maxId + 1;
            String name = thr.name();
            int iDot = name.lastIndexOf('.');
            if (iDot >= 0 && name.length() > iDot) {
                name = name.substring(iDot + 1);
            }
            sbOut.insert(iBuf, name);
            iBuf += maxName + 1;
            sbOut.insert(iBuf, Utils.getStatus(thr));
            sbOut.setLength(79);
            out.println(sbOut.toString());
        }
        List tglist = tg.threadGroups();
        for (int ig = 0; ig < tglist.size(); ig++) {
            ThreadGroupReference tg0 = (ThreadGroupReference)tglist.get(ig);
            if (!tg.equals(tg0)) {  // TODO ref mgt
                iThread += printThreadGroup(out, tg0, iThread + tlist.size());
            }
        }
        return tlist.size();
    }

    // Command: threadgroups

    private void commandThreadGroups() throws NoSessionException {
        ThreadGroupIterator it = allThreadGroups();
        int cnt = 0;
        OutputSink out = env.getOutputSink();
        while (it.hasNext()) {
            ThreadGroupReference tg = it.nextThreadGroup();
            ++cnt;
            out.println("" + cnt + ". " + Utils.description(tg) + " " + tg.name());
        }
        out.show();
    }

    // Command: thread

    private void commandThread(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("Thread number not specified.");
            return;
        }
        ThreadReference thread = findThread(t.nextToken());
        if (thread != null) {
            //### Should notify user.
            context.setCurrentThread(thread);
        }
    }

    // Command: threadgroup

    private void commandThreadGroup(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("Threadgroup name not specified.");
            return;
        }
        String name = t.nextToken();
        ThreadGroupReference tg = findThreadGroup(name);
        if (tg == null) {
            env.failure(name + " is not a valid threadgroup name.");
        } else {
            //### Should notify user.
            setDefaultThreadGroup(tg);
        }
    }

    // Command: run

    private void commandRun(StringTokenizer t) throws NoSessionException {
        if (doLoad(false, t)) {
            env.notice("Running ...");
        }
    }

    // Command: load

    private void commandLoad(StringTokenizer t) throws NoSessionException {
        if (doLoad(true, t)) {}
    }

    private boolean doLoad(boolean suspended,
                           StringTokenizer t) throws NoSessionException {

        String clname;

        if (!t.hasMoreTokens()) {
            clname = context.getMainClassName();
            if (!clname.equals("")) {
                // Run from prevously-set class name.
                try {
                    String vmArgs = context.getVmArguments();
                    runtime.run(suspended,
                                vmArgs,
                                clname,
                                context.getProgramArguments());
                    return true;
                } catch (VMLaunchFailureException e) {
                    env.failure("Attempt to launch main class \"" + clname + "\" failed.");
                }
            } else {
                env.failure("No main class specifed and no current default defined.");
            }
        } else {
            clname = t.nextToken();
            StringBuffer sbuf = new StringBuffer();
            // Allow VM arguments to be specified here?
            while (t.hasMoreTokens()) {
                String tok = t.nextToken();
                sbuf.append(tok);
                if (t.hasMoreTokens()) {
                    sbuf.append(' ');
                }
            }
            String args = sbuf.toString();
            try {
                String vmArgs = context.getVmArguments();
                runtime.run(suspended, vmArgs, clname, args);
                context.setMainClassName(clname);
                //context.setVmArguments(vmArgs);
                context.setProgramArguments(args);
                return true;
            } catch (VMLaunchFailureException e) {
                env.failure("Attempt to launch main class \"" + clname + "\" failed.");
            }
        }
        return false;
    }

    // Command: connect

    private void commandConnect(StringTokenizer t) {
        try {
            LaunchTool.queryAndLaunchVM(runtime);
        } catch (VMLaunchFailureException e) {
            env.failure("Attempt to connect failed.");
        }
    }

    // Command: attach

    private void commandAttach(StringTokenizer t) {
        String portName;
        if (!t.hasMoreTokens()) {
            portName = context.getRemotePort();
            if (!portName.equals("")) {
                try {
                    runtime.attach(portName);
                } catch (VMLaunchFailureException e) {
                    env.failure("Attempt to attach to port \"" + portName + "\" failed.");
                }
            } else {
                env.failure("No port specifed and no current default defined.");
            }
        } else {
            portName = t.nextToken();
            try {
                runtime.attach(portName);
            } catch (VMLaunchFailureException e) {
                env.failure("Attempt to attach to port \"" + portName + "\" failed.");
            }
            context.setRemotePort(portName);
        }
    }

    // Command: detach

    private void commandDetach(StringTokenizer t) throws NoSessionException {
        runtime.detach();
    }

    // Command: interrupt

    private void commandInterrupt(StringTokenizer t) throws NoSessionException {
        runtime.interrupt();
    }

    // Command: suspend

    private void commandSuspend(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            // Suspend all threads in the current thread group.
            //### Issue: help message says default is all threads.
            //### Behavior here agrees with 'jdb', however.
            ThreadIterator ti = currentThreadGroupThreads();
            while (ti.hasNext()) {
                // TODO - don't suspend debugger threads
                ti.nextThread().suspend();
            }
            env.notice("All (non-system) threads suspended.");
        } else {
            while (t.hasMoreTokens()) {
                ThreadReference thread = findThread(t.nextToken());
                if (thread != null) {
                    //thread.suspend();
                    runtime.suspendThread(thread);
                }
            }
        }
    }

    // Command: resume

    private void commandResume(StringTokenizer t) throws NoSessionException {
         if (!t.hasMoreTokens()) {
            // Suspend all threads in the current thread group.
            //### Issue: help message says default is all threads.
            //### Behavior here agrees with 'jdb', however.
            ThreadIterator ti = currentThreadGroupThreads();
            while (ti.hasNext()) {
                // TODO - don't suspend debugger threads
                ti.nextThread().resume();
            }
            env.notice("All threads resumed.");
         } else {
             while (t.hasMoreTokens()) {
                ThreadReference thread = findThread(t.nextToken());
                if (thread != null) {
                    //thread.resume();
                    runtime.resumeThread(thread);
                }
             }
         }
    }

    // Command: cont

    private void commandCont() throws NoSessionException {
        try {
            runtime.go();
        } catch (VMNotInterruptedException e) {
            //### failure?
            env.notice("Target VM is already running.");
        }
    }

    // Command: step

    private void commandStep(StringTokenizer t) throws NoSessionException{
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        try {
            if (t.hasMoreTokens() &&
                t.nextToken().toLowerCase().equals("up")) {
                runtime.stepOut(current);
            } else {
                runtime.stepIntoLine(current);
            }
        } catch (AbsentInformationException e) {
            env.failure("No linenumber information available -- " +
                            "Try \"stepi\" to step by instructions.");
        }
    }

    // Command: stepi

    private void commandStepi() throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        runtime.stepIntoInstruction(current);
    }

    // Command: next

    private void commandNext() throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        try {
            runtime.stepOverLine(current);
        } catch (AbsentInformationException e) {
            env.failure("No linenumber information available -- " +
                            "Try \"nexti\" to step by instructions.");
        }
    }

    // Command: nexti  (NEW)

    private void commandNexti() throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        runtime.stepOverInstruction(current);
    }

    // Command: kill

    private void commandKill(StringTokenizer t) throws NoSessionException {
        //### Should change the way in which thread ids and threadgroup names
        //### are distinguished.
         if (!t.hasMoreTokens()) {
            env.error("Usage: kill <threadgroup name> or <thread id>");
            return;
        }
        while (t.hasMoreTokens()) {
            String idToken = t.nextToken();
            ThreadReference thread = findThread(idToken);
            if (thread != null) {
                runtime.stopThread(thread);
                env.notice("Thread " + thread.name() + " killed.");
                return;
            } else {
                /* Check for threadgroup name, NOT skipping "system". */
                //### Should skip "system"?  Classic 'jdb' does this.
                //### Should deal with possible non-uniqueness of threadgroup names.
                ThreadGroupIterator itg = allThreadGroups();
                while (itg.hasNext()) {
                    ThreadGroupReference tg = itg.nextThreadGroup();
                    if (tg.name().equals(idToken)) {
                        ThreadIterator it = new ThreadIterator(tg);
                        while (it.hasNext()) {
                            runtime.stopThread(it.nextThread());
                        }
                        env.notice("Threadgroup " + tg.name() + "killed.");
                        return;
                    }
                }
                env.failure("\"" + idToken +
                            "\" is not a valid threadgroup or id.");
            }
        }
    }


    /*************
    // TODO
    private void commandCatchException(StringTokenizer t) throws NoSessionException {}
    // TODO
    private void commandIgnoreException(StringTokenizer t) throws NoSessionException {}
    *************/

    // Command: up

    //### Print current frame after command?

    int readCount(StringTokenizer t) {
        int cnt = 1;
        if (t.hasMoreTokens()) {
            String idToken = t.nextToken();
            int n;
            try {
                cnt = Integer.valueOf(idToken).intValue();
            } catch (NumberFormatException e) {
                cnt = -1;
            }
        }
        return cnt;
    }

    void commandUp(StringTokenizer t) throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        int nLevels = readCount(t);
        if (nLevels <= 0) {
            env.error("usage: up [n frames]");
            return;
        }
        try {
            int delta = context.moveCurrentFrameIndex(current, -nLevels);
            if (delta == 0) {
                env.notice("Already at top of stack.");
            } else if (-delta < nLevels) {
                env.notice("Moved up " + delta + " frames to top of stack.");
            }
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
        }
    }

    private void commandDown(StringTokenizer t) throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        int nLevels = readCount(t);
        if (nLevels <= 0) {
            env.error("usage: down [n frames]");
            return;
        }
        try {
            int delta = context.moveCurrentFrameIndex(current, nLevels);
            if (delta == 0) {
                env.notice("Already at bottom of stack.");
            } else if (delta < nLevels) {
                env.notice("Moved down " + delta + " frames to bottom of stack.");
            }
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
        }
    }

    // Command: frame

    private void commandFrame(StringTokenizer t) throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No current thread.");
            return;
        }
        if (!t.hasMoreTokens()) {
            env.error("usage: frame <frame-index>");
            return;
        }
        String idToken = t.nextToken();
        int n;
        try {
            n = Integer.valueOf(idToken).intValue();
        } catch (NumberFormatException e) {
            n = 0;
        }
        if (n <= 0) {
            env.error("use positive frame index");
            return;
        }
        try {
            int delta = context.setCurrentFrameIndex(current, n);
            if (delta == 0) {
                env.notice("Frame unchanged.");
            } else if (delta < 0) {
                env.notice("Moved up " + -delta + " frames.");
            } else {
                env.notice("Moved down " + delta + " frames.");
            }
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
        }
    }

    // Command: where

    //### Should we insist that VM be interrupted here?
    //### There is an inconsistency between the 'where' command
    //### and 'up' and 'down' in this respect.

    private void commandWhere(StringTokenizer t, boolean showPC)
                                                throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (!t.hasMoreTokens()) {
            if (current == null) {
                env.error("No thread specified.");
                return;
            }
            dumpStack(current, showPC);
        } else {
            String token = t.nextToken();
            if (token.toLowerCase().equals("all")) {
                ThreadIterator it = allThreads();
                while (it.hasNext()) {
                    ThreadReference thread = (ThreadReference)it.next();
                    out.println(thread.name() + ": ");
                    dumpStack(thread, showPC);
                }
            } else {
                ThreadReference thread = findThread(t.nextToken());
                //### Do we want to set current thread here?
                //### Should notify user of change.
                if (thread != null) {
                    context.setCurrentThread(thread);
                }
                dumpStack(thread, showPC);
            }
        }
    }

    private void dumpStack(ThreadReference thread, boolean showPC) {
        //### Check for these.
        //env.failure("Thread no longer exists.");
        //env.failure("Target VM must be in interrupted state.");
        //env.failure("Current thread isn't suspended.");
        //### Should handle extremely long stack traces sensibly for user.
        List stack = null;
        try {
            stack = thread.frames();
        } catch (IncompatibleThreadStateException e) {
            env.failure("Thread is not suspended.");
        }
        //### Fix this!
        //### Previously mishandled cases where thread was not current.
        //### Now, prints all of the stack regardless of current frame.
        int frameIndex = 0;
        //int frameIndex = context.getCurrentFrameIndex();
        if (stack == null) {
            env.failure("Thread is not running (no stack).");
        } else {
            OutputSink out = env.getOutputSink();
            int nFrames = stack.size();
            for (int i = frameIndex; i < nFrames; i++) {
                StackFrame frame = (StackFrame)stack.get(i);
                Location loc = frame.location();
                Method meth = loc.method();
                out.print("  [" + (i + 1) + "] ");
                out.print(meth.declaringType().name());
                out.print('.');
                out.print(meth.name());
                out.print(" (");
                if (meth instanceof Method && ((Method)meth).isNative()) {
                    out.print("native method");
                } else if (loc.lineNumber() != -1) {
                    try {
                        out.print(loc.sourceName());
                    } catch (AbsentInformationException e) {
                        out.print("<unknown>");
                    }
                    out.print(':');
                    out.print(loc.lineNumber());
                }
                out.print(')');
                if (showPC) {
                    long pc = loc.codeIndex();
                    if (pc != -1) {
                        out.print(", pc = " + pc);
                    }
                }
                out.println();
            }
            out.show();
        }
    }

    private void listEventRequests() throws NoSessionException {
        // Print set breakpoints
        Iterator iter = runtime.eventRequestSpecs().iterator();
        if (!iter.hasNext()) {
            env.notice("No breakpoints/watchpoints/exceptions set.");
        } else {
            OutputSink out = env.getOutputSink();
            out.println("Current breakpoints/watchpoints/exceptions set:");
            while (iter.hasNext()) {
                EventRequestSpec  bp = (EventRequestSpec)iter.next();
                out.println("\t" + bp);
            }
            out.show();
        }
    }

    private BreakpointSpec parseBreakpointSpec(String bptSpec) {
        StringTokenizer t = new StringTokenizer(bptSpec);
        BreakpointSpec bpSpec = null;
//        try {
            String token = t.nextToken("@:( \t\n\r");
            // We can't use hasMoreTokens here because it will cause any leading
            // paren to be lost.
            String rest;
            try {
                rest = t.nextToken("").trim();
            } catch (NoSuchElementException e) {
                rest = null;
            }
            if ((rest != null) && rest.startsWith("@")) {
                t = new StringTokenizer(rest.substring(1));
                String sourceName = token;
                String lineToken = t.nextToken();
                int lineNumber = Integer.valueOf(lineToken).intValue();
                if (t.hasMoreTokens()) {
                    return null;
                }
                bpSpec = runtime.createSourceLineBreakpoint(sourceName,
                                                            lineNumber);
            } else if ((rest != null) && rest.startsWith(":")) {
                t = new StringTokenizer(rest.substring(1));
                String classId = token;
                String lineToken = t.nextToken();
                int lineNumber = Integer.valueOf(lineToken).intValue();
                if (t.hasMoreTokens()) {
                    return null;
                }
                bpSpec = runtime.createClassLineBreakpoint(classId, lineNumber);
            } else {
                // Try stripping method from class.method token.
                int idot = token.lastIndexOf(".");
                if ( (idot <= 0) ||        /* No dot or dot in first char */
                     (idot >= token.length() - 1) ) { /* dot in last char */
                    return null;
                }
                String methodName = token.substring(idot + 1);
                String classId = token.substring(0, idot);
                List<String> argumentList = null;
                if (rest != null) {
                    if (!rest.startsWith("(") || !rest.endsWith(")")) {
                        //### Should throw exception with error message
                        //out.println("Invalid method specification: "
                        //            + methodName + rest);
                        return null;
                    }
                    // Trim the parens
                    //### What about spaces in arglist?
                    rest = rest.substring(1, rest.length() - 1);
                    argumentList = new ArrayList<String>();
                    t = new StringTokenizer(rest, ",");
                    while (t.hasMoreTokens()) {
                        argumentList.add(t.nextToken());
                    }
                }
                bpSpec = runtime.createMethodBreakpoint(classId,
                                                       methodName,
                                                       argumentList);
            }
//        } catch (Exception e) {
//            env.error("Exception attempting to create breakpoint: " + e);
//            return null;
//        }
        return bpSpec;
    }

    private void commandStop(StringTokenizer t) throws NoSessionException {
        Location bploc;
        String token;

        if (!t.hasMoreTokens()) {
            listEventRequests();
        } else {
            token = t.nextToken();
            // Ignore optional "at" or "in" token.
            // Allowed for backward compatibility.
            if (token.equals("at") || token.equals("in")) {
                if (t.hasMoreTokens()) {
                    token = t.nextToken();
                } else {
                    env.error("Missing breakpoint specification.");
                    return;
                }
            }
            BreakpointSpec bpSpec = parseBreakpointSpec(token);
            if (bpSpec != null) {
                //### Add sanity-checks for deferred breakpoint.
                runtime.install(bpSpec);
            } else {
                env.error("Ill-formed breakpoint specification.");
            }
        }
    }

    private void commandClear(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            // Print set breakpoints
            listEventRequests();
            return;
        }
        //### need 'clear all'
        BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken());
        if (bpSpec != null) {
            Iterator iter = runtime.eventRequestSpecs().iterator();
            if (!iter.hasNext()) {
                env.notice("No breakpoints set.");
            } else {
                List<BreakpointSpec> toDelete = new ArrayList<BreakpointSpec>();
                while (iter.hasNext()) {
                    BreakpointSpec spec = (BreakpointSpec)iter.next();
                    if (spec.equals(bpSpec)) {
                        toDelete.add(spec);
                    }
                }
                // The request used for matching should be found
                if (toDelete.size() <= 1) {
                    env.notice("No matching breakpoint set.");
                }
                for (BreakpointSpec spec : toDelete) {
                    runtime.delete(spec);
                }
            }
        } else {
            env.error("Ill-formed breakpoint specification.");
        }
    }

    // Command: list

    private void commandList(StringTokenizer t) throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.error("No thread specified.");
            return;
        }
        Location loc;
        try {
            StackFrame frame = context.getCurrentFrame(current);
            if (frame == null) {
                env.failure("Thread has not yet begun execution.");
                return;
            }
            loc = frame.location();
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
            return;
        }
        SourceModel source = sourceManager.sourceForLocation(loc);
        if (source == null) {
            if (loc.method().isNative()) {
                env.failure("Current method is native.");
                return;
            }
            env.failure("No source available for " + Utils.locationString(loc) + ".");
            return;
        }
        ReferenceType refType = loc.declaringType();
        int lineno = loc.lineNumber();
        if (t.hasMoreTokens()) {
            String id = t.nextToken();
            // See if token is a line number.
            try {
                lineno = Integer.valueOf(id).intValue();
            } catch (NumberFormatException nfe) {
                // It isn't -- see if it's a method name.
                List meths = refType.methodsByName(id);
                if (meths == null || meths.size() == 0) {
                    env.failure(id +
                                " is not a valid line number or " +
                                "method name for class " +
                                refType.name());
                    return;
                } else if (meths.size() > 1) {
                    env.failure(id +
                                " is an ambiguous method name in" +
                                refType.name());
                    return;
                }
                loc = ((Method)meths.get(0)).location();
                lineno = loc.lineNumber();
            }
        }
        int startLine = (lineno > 4) ? lineno - 4 : 1;
        int endLine = startLine + 9;
        String sourceLine = source.sourceLine(lineno);
        if (sourceLine == null) {
            env.failure("" +
                        lineno +
                        " is an invalid line number for " +
                        refType.name());
        } else {
            OutputSink out = env.getOutputSink();
            for (int i = startLine; i <= endLine; i++) {
                sourceLine = source.sourceLine(i);
                if (sourceLine == null) {
                    break;
                }
                out.print(i);
                out.print("\t");
                if (i == lineno) {
                    out.print("=> ");
                } else {
                    out.print("   ");
                }
                out.println(sourceLine);
            }
            out.show();
        }
    }

    // Command: use
    // Get or set the source file path list.

    private void commandUse(StringTokenizer t) {
        if (!t.hasMoreTokens()) {
            out.println(sourceManager.getSourcePath().asString());
        } else {
            //### Should throw exception for invalid path.
            //### E.g., vetoable property change.
            sourceManager.setSourcePath(new SearchPath(t.nextToken()));
        }
    }

    // Command: sourcepath
    // Get or set the source file path list.  (Alternate to 'use'.)

    private void commandSourcepath(StringTokenizer t) {
        if (!t.hasMoreTokens()) {
            out.println(sourceManager.getSourcePath().asString());
        } else {
            //### Should throw exception for invalid path.
            //### E.g., vetoable property change.
            sourceManager.setSourcePath(new SearchPath(t.nextToken()));
        }
    }

    // Command: classpath
    // Get or set the class file path list.

    private void commandClasspath(StringTokenizer t) {
        if (!t.hasMoreTokens()) {
            out.println(classManager.getClassPath().asString());
        } else {
            //### Should throw exception for invalid path.
            //### E.g., vetoable property change.
            classManager.setClassPath(new SearchPath(t.nextToken()));
        }
    }

    // Command: view
    // Display source for source file or class.

    private void commandView(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("Argument required");
        } else {
            String name = t.nextToken();
            if (name.endsWith(".java") ||
                name.indexOf(File.separatorChar) >= 0) {
                env.viewSource(name);
            } else {
                //### JDI crashes taking line number for class.
                /*****
                ReferenceType cls = findClass(name);
                if (cls != null) {
                    env.viewLocation(cls.location());
                } else {
                    env.failure("No such class");
                }
                *****/
                String fileName = name.replace('.', File.separatorChar) + ".java";
                env.viewSource(fileName);
            }
        }
    }

    // Command: locals
    // Print all local variables in current stack frame.

    private void commandLocals() throws NoSessionException {
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No default thread specified: " +
                        "use the \"thread\" command first.");
            return;
        }
        StackFrame frame;
        try {
            frame = context.getCurrentFrame(current);
            if (frame == null) {
                env.failure("Thread has not yet created any stack frames.");
                return;
            }
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
            return;
        }

        List vars;
        try {
            vars = frame.visibleVariables();
            if (vars == null || vars.size() == 0) {
                env.failure("No local variables");
                return;
            }
        } catch (AbsentInformationException e) {
            env.failure("Local variable information not available." +
                        " Compile with -g to generate variable information");
            return;
        }

        OutputSink out = env.getOutputSink();
        out.println("Method arguments:");
        for (Iterator it = vars.iterator(); it.hasNext(); ) {
            LocalVariable var = (LocalVariable)it.next();
            if (var.isArgument()) {
                printVar(out, var, frame);
            }
        }
        out.println("Local variables:");
        for (Iterator it = vars.iterator(); it.hasNext(); ) {
            LocalVariable var = (LocalVariable)it.next();
            if (!var.isArgument()) {
                printVar(out, var, frame);
            }
        }
        out.show();
        return;
    }

    /**
     * Command: monitor
     * Monitor an expression
     */
    private void commandMonitor(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("Argument required");
        } else {
            env.getMonitorListModel().add(t.nextToken(""));
        }
    }

    /**
     * Command: unmonitor
     * Unmonitor an expression
     */
    private void commandUnmonitor(StringTokenizer t) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            env.error("Argument required");
        } else {
            env.getMonitorListModel().remove(t.nextToken(""));
        }
    }

    // Print a stack variable.

    private void printVar(OutputSink out, LocalVariable var, StackFrame frame) {
        out.print("  " + var.name());
        if (var.isVisible(frame)) {
            Value val = frame.getValue(var);
            out.println(" = " + val.toString());
        } else {
            out.println(" is not in scope");
        }
    }

    // Command: print
    // Evaluate an expression.

    private void commandPrint(StringTokenizer t, boolean dumpObject) throws NoSessionException {
        if (!t.hasMoreTokens()) {
            //### Probably confused if expresion contains whitespace.
            env.error("No expression specified.");
            return;
        }
        ThreadReference current = context.getCurrentThread();
        if (current == null) {
            env.failure("No default thread specified: " +
                        "use the \"thread\" command first.");
            return;
        }
        StackFrame frame;
        try {
            frame = context.getCurrentFrame(current);
            if (frame == null) {
                env.failure("Thread has not yet created any stack frames.");
                return;
            }
        } catch (VMNotInterruptedException e) {
            env.failure("Target VM must be in interrupted state.");
            return;
        }
        while (t.hasMoreTokens()) {
            String expr = t.nextToken("");
            Value val = null;
            try {
                val = runtime.evaluate(frame, expr);
            } catch(Exception e) {
                env.error("Exception: " + e);
                //### Fix this!
            }
            if (val == null) {
                return;  // Error message already printed
            }
            OutputSink out = env.getOutputSink();
            if (dumpObject && (val instanceof ObjectReference) &&
                                 !(val instanceof StringReference)) {
                ObjectReference obj = (ObjectReference)val;
                ReferenceType refType = obj.referenceType();
                out.println(expr + " = " + val.toString() + " {");
                dump(out, obj, refType, refType);
                out.println("}");
            } else {
                out.println(expr + " = " + val.toString());
            }
            out.show();
        }
    }

    private void dump(OutputSink out,
                      ObjectReference obj, ReferenceType refType,
                      ReferenceType refTypeBase) {
        for (Iterator it = refType.fields().iterator(); it.hasNext(); ) {
            Field field = (Field)it.next();
            out.print("    ");
            if (!refType.equals(refTypeBase)) {
                out.print(refType.name() + ".");
            }
            out.print(field.name() + ": ");
            Object o = obj.getValue(field);
            out.println((o == null) ? "null" : o.toString()); // Bug ID 4374471
        }
        if (refType instanceof ClassType) {
            ClassType sup = ((ClassType)refType).superclass();
            if (sup != null) {
                dump(out, obj, sup, refTypeBase);
            }
        } else if (refType instanceof InterfaceType) {
            List sups = ((InterfaceType)refType).superinterfaces();
            for (Iterator it = sups.iterator(); it.hasNext(); ) {
                dump(out, obj, (ReferenceType)it.next(), refTypeBase);
            }
        }
    }

    /*
     * Display help message.
     */

    private void help() {
        out.println("** command list **");
        out.println("threads [threadgroup]     -- list threads");
        out.println("thread <thread id>        -- set default thread");
        out.println("suspend [thread id(s)]    -- suspend threads (default: all)");
        out.println("resume [thread id(s)]     -- resume threads (default: all)");
        out.println("where [thread id] | all   -- dump a thread's stack");
        out.println("wherei [thread id] | all  -- dump a thread's stack, with pc info");
        out.println("threadgroups              -- list threadgroups");
        out.println("threadgroup <name>        -- set current threadgroup\n");
//      out.println("print <expression>        -- print value of expression");
        out.println("dump <expression>         -- print all object information\n");
//      out.println("eval <expression>         -- evaluate expression (same as print)");
        out.println("locals                    -- print all local variables in current stack frame\n");
        out.println("classes                   -- list currently known classes");
        out.println("methods <class id>        -- list a class's methods\n");
        out.println("stop [in] <class id>.<method>[(argument_type,...)] -- set a breakpoint in a method");
        out.println("stop [at] <class id>:<line> -- set a breakpoint at a line");
        out.println("up [n frames]             -- move up a thread's stack");
        out.println("down [n frames]           -- move down a thread's stack");
        out.println("frame <frame-id>           -- to a frame");
        out.println("clear <class id>.<method>[(argument_type,...)]   -- clear a breakpoint in a method");
        out.println("clear <class id>:<line>   -- clear a breakpoint at a line");
        out.println("clear                     -- list breakpoints");
        out.println("step                      -- execute current line");
        out.println("step up                   -- execute until the current method returns to its caller");
        out.println("stepi                     -- execute current instruction");
        out.println("next                      -- step one line (step OVER calls)");
        out.println("nexti                     -- step one instruction (step OVER calls)");
        out.println("cont                      -- continue execution from breakpoint\n");
//      out.println("catch <class id>          -- break for the specified exception");
//      out.println("ignore <class id>         -- ignore when the specified exception\n");
        out.println("view classname|filename   -- display source file");
        out.println("list [line number|method] -- print source code context at line or method");
        out.println("use <source file path>    -- display or change the source path\n");
//### new
        out.println("sourcepath <source file path>    -- display or change the source path\n");
//### new
        out.println("classpath <class file path>    -- display or change the class path\n");
        out.println("monitor <expression>      -- evaluate an expression each time the program stops\n");
        out.println("unmonitor <monitor#>      -- delete a monitor\n");
        out.println("read <filename>           -- read and execute a command file\n");
//      out.println("memory                    -- report memory usage");
//      out.println("gc                        -- free unused objects\n");
        out.println("run <class> [args]        -- start execution of a Java class");
        out.println("run                       -- re-execute last class run");
        out.println("load <class> [args]       -- start execution of a Java class, initially suspended");
        out.println("load                      -- re-execute last class run, initially suspended");
        out.println("attach <portname>         -- debug existing process\n");
        out.println("detach                    -- detach from debuggee process\n");
        out.println("kill <thread(group)>      -- kill a thread or threadgroup\n");
        out.println("!!                        -- repeat last command");
        out.println("help (or ?)               -- list commands");
        out.println("exit (or quit)            -- exit debugger");
    }

    /*
     * Execute a command.
     */

    public void executeCommand(String command) {
        //### Treatment of 'out' here is dirty...
        out = env.getOutputSink();
        if (echo) {
            out.println(">>> " + command);
        }
        StringTokenizer t = new StringTokenizer(command);
        try {
            String cmd;
            if (t.hasMoreTokens()) {
                cmd = t.nextToken().toLowerCase();
                lastCommand = cmd;
            } else {
                cmd = lastCommand;
            }
            if (cmd.equals("print")) {
                commandPrint(t, false);
            } else if (cmd.equals("eval")) {
                commandPrint(t, false);
            } else if (cmd.equals("dump")) {
                commandPrint(t, true);
            } else if (cmd.equals("locals")) {
                commandLocals();
            } else if (cmd.equals("classes")) {
                commandClasses();
            } else if (cmd.equals("methods")) {
                commandMethods(t);
            } else if (cmd.equals("threads")) {
                commandThreads(t);
            } else if (cmd.equals("thread")) {
                commandThread(t);
            } else if (cmd.equals("suspend")) {
                commandSuspend(t);
            } else if (cmd.equals("resume")) {
                commandResume(t);
            } else if (cmd.equals("cont")) {
                commandCont();
            } else if (cmd.equals("threadgroups")) {
                commandThreadGroups();
            } else if (cmd.equals("threadgroup")) {
                commandThreadGroup(t);
            } else if (cmd.equals("run")) {
                commandRun(t);
            } else if (cmd.equals("load")) {
                commandLoad(t);
            } else if (cmd.equals("connect")) {
                commandConnect(t);
            } else if (cmd.equals("attach")) {
                commandAttach(t);
            } else if (cmd.equals("detach")) {
                commandDetach(t);
            } else if (cmd.equals("interrupt")) {
                commandInterrupt(t);
//### Not implemented.
//          } else if (cmd.equals("catch")) {
//              commandCatchException(t);
//### Not implemented.
//          } else if (cmd.equals("ignore")) {
//              commandIgnoreException(t);
            } else if (cmd.equals("step")) {
                commandStep(t);
            } else if (cmd.equals("stepi")) {
                commandStepi();
            } else if (cmd.equals("next")) {
                commandNext();
            } else if (cmd.equals("nexti")) {
                commandNexti();
            } else if (cmd.equals("kill")) {
                commandKill(t);
            } else if (cmd.equals("where")) {
                commandWhere(t, false);
            } else if (cmd.equals("wherei")) {
                commandWhere(t, true);
            } else if (cmd.equals("up")) {
                commandUp(t);
            } else if (cmd.equals("down")) {
                commandDown(t);
            } else if (cmd.equals("frame")) {
                commandFrame(t);
            } else if (cmd.equals("stop")) {
                commandStop(t);
            } else if (cmd.equals("clear")) {
                commandClear(t);
            } else if (cmd.equals("list")) {
                commandList(t);
            } else if (cmd.equals("use")) {
                commandUse(t);
            } else if (cmd.equals("sourcepath")) {
                commandSourcepath(t);
            } else if (cmd.equals("classpath")) {
                commandClasspath(t);
            } else if (cmd.equals("monitor")) {
                commandMonitor(t);
            } else if (cmd.equals("unmonitor")) {
                commandUnmonitor(t);
            } else if (cmd.equals("view")) {
                commandView(t);
//          } else if (cmd.equals("read")) {
//              readCommand(t);
            } else if (cmd.equals("help") || cmd.equals("?")) {
                help();
            } else if (cmd.equals("quit") || cmd.equals("exit")) {
                try {
                    runtime.detach();
                } catch (NoSessionException e) {
                    // ignore
                }
                env.terminate();
            } else {
                //### Dubious repeat-count feature inherited from 'jdb'
                if (t.hasMoreTokens()) {
                    try {
                        int repeat = Integer.parseInt(cmd);
                        String subcom = t.nextToken("");
                        while (repeat-- > 0) {
                            executeCommand(subcom);
                        }
                        return;
                    } catch (NumberFormatException exc) {
                    }
                }
                out.println("huh? Try help...");
                out.flush();
            }
        } catch (NoSessionException e) {
            out.println("There is no currently attached VM session.");
            out.flush();
        } catch (Exception e) {
            out.println("Internal exception: " + e.toString());
            out.flush();
            System.out.println("JDB internal exception: " + e.toString());
            e.printStackTrace();
        }
        out.show();
    }
}
