/*
 *  Minimal debug web console for Duktape command line tool
 *
 *  See debugger/README.rst.
 *
 *  The web UI socket.io communication can easily become a bottleneck and
 *  it's important to ensure that the web UI remains responsive.  Basic rate
 *  limiting mechanisms (token buckets, suppressing identical messages, etc)
 *  are used here now.  Ideally the web UI would pull data on its own terms
 *  which would provide natural rate limiting.
 *
 *  Promises are used to structure callback chains.
 *
 *  https://github.com/petkaantonov/bluebird
 *  https://github.com/petkaantonov/bluebird/blob/master/API.md
 *  https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns
 */

var Promise = require('bluebird');
var events = require('events');
var stream = require('stream');
var path = require('path');
var fs = require('fs');
var net = require('net');
var byline = require('byline');
var util = require('util');
var readline = require('readline');
var sprintf = require('sprintf').sprintf;
var utf8 = require('utf8');
var wrench = require('wrench');  // https://github.com/ryanmcgrath/wrench-js
var yaml = require('yamljs');

// Command line options (defaults here, overwritten if necessary)
var optTargetHost = '127.0.0.1';
var optTargetPort = 9091;
var optHttpPort = 9092;
var optJsonProxyPort = 9093;
var optJsonProxy = false;
var optSourceSearchDirs = [ '../tests/ecmascript' ];
var optDumpDebugRead = null;
var optDumpDebugWrite = null;
var optDumpDebugPretty = null;
var optLogMessages = false;

// Constants
var UI_MESSAGE_CLIPLEN = 128;
var LOCALS_CLIPLEN = 64;
var EVAL_CLIPLEN = 4096;
var GETVAR_CLIPLEN = 4096;

// Commands initiated by Duktape
var CMD_STATUS = 0x01;
var CMD_PRINT = 0x02;
var CMD_ALERT = 0x03;
var CMD_LOG = 0x04;
var CMD_THROW = 0x05;
var CMD_DETACHING = 0x06;

// Commands initiated by the debug client (= us)
var CMD_BASICINFO = 0x10;
var CMD_TRIGGERSTATUS = 0x11;
var CMD_PAUSE = 0x12;
var CMD_RESUME = 0x13;
var CMD_STEPINTO = 0x14;
var CMD_STEPOVER = 0x15;
var CMD_STEPOUT = 0x16;
var CMD_LISTBREAK = 0x17;
var CMD_ADDBREAK = 0x18;
var CMD_DELBREAK = 0x19;
var CMD_GETVAR = 0x1a;
var CMD_PUTVAR = 0x1b;
var CMD_GETCALLSTACK = 0x1c;
var CMD_GETLOCALS = 0x1d;
var CMD_EVAL = 0x1e;
var CMD_DETACH = 0x1f;
var CMD_DUMPHEAP = 0x20;
var CMD_GETBYTECODE = 0x21;

// Errors
var ERR_UNKNOWN = 0x00;
var ERR_UNSUPPORTED = 0x01;
var ERR_TOOMANY = 0x02;
var ERR_NOTFOUND = 0x03;

// Marker objects for special protocol values
var DVAL_EOM = { type: 'eom' };
var DVAL_REQ = { type: 'req' };
var DVAL_REP = { type: 'rep' };
var DVAL_ERR = { type: 'err' };
var DVAL_NFY = { type: 'nfy' };

// String map for commands (debug dumping).  A single map works (instead of
// separate maps for each direction) because command numbers don't currently
// overlap.  So merge the YAML metadata.
var debugCommandMeta = yaml.load('duk_debugcommands.yaml');
var debugCommandNames = [];  // list of command names, merged client/target
debugCommandMeta.target_commands.forEach(function (k, i) {
    debugCommandNames[i] = k;
});
debugCommandMeta.client_commands.forEach(function (k, i) {  // override
    debugCommandNames[i] = k;
});
var debugCommandNumbers = {};  // map from (merged) command name to number
debugCommandNames.forEach(function (k, i) {
    debugCommandNumbers[k] = i;
});

// Duktape heaphdr type constants, must match C headers
var DUK_HTYPE_STRING = 1;
var DUK_HTYPE_OBJECT = 2;
var DUK_HTYPE_BUFFER = 3;

// Duktape internal class numbers, must match C headers
var dukClassNameMeta = yaml.load('duk_classnames.yaml');
var dukClassNames = dukClassNameMeta.class_names;

// Bytecode opcode/extraop metadata
var dukOpcodes = yaml.load('duk_opcodes.yaml');
if (dukOpcodes.opcodes.length != 64) {
    throw new Error('opcode metadata length incorrect');
}
if (dukOpcodes.extra.length != 256) {
    throw new Error('extraop metadata length incorrect');
}

/*
 *  Miscellaneous helpers
 */

var nybbles = '0123456789abcdef';

/* Convert a buffer into a string using Unicode codepoints U+0000...U+00FF.
 * This is the NodeJS 'binary' encoding, but since it's being deprecated,
 * reimplement it here.  We need to avoid parsing strings as e.g. UTF-8:
 * although Duktape strings are usually UTF-8/CESU-8 that's not always the
 * case, e.g. for internal strings.  Buffer values are also represented as
 * strings in the debug protocol, so we must deal accurately with arbitrary
 * byte arrays.
 */
function bufferToDebugString(buf) {
    var cp = [];
    var i, n;

/*
    // This fails with "RangeError: Maximum call stack size exceeded" for some
    // reason, so use a much slower variant.

    for (i = 0, n = buf.length; i < n; i++) {
        cp[i] = buf[i];
    }

    return String.fromCharCode.apply(String, cp);
*/

    for (i = 0, n = buf.length; i < n; i++) {
        cp[i] = String.fromCharCode(buf[i]);
    }

    return cp.join('');
}

/* Write a string into a buffer interpreting codepoints U+0000...U+00FF
 * as bytes.  Drop higher bits.
 */
function writeDebugStringToBuffer(str, buf, off) {
    var i, n;

    for (i = 0, n = str.length; i < n; i++) {
        buf[off + i] = str.charCodeAt(i) & 0xff;  // truncate higher bits
    }
}

/* Encode an ordinary Unicode string into a dvalue compatible format, i.e.
 * into a byte array represented as codepoints U+0000...U+00FF.  Concretely,
 * encode with UTF-8 and then represent the bytes with U+0000...U+00FF.
 */
function stringToDebugString(str) {
    return utf8.encode(str);
}

/* Pretty print a dvalue.  Useful for dumping etc. */
function prettyDebugValue(x) {
    if (typeof x === 'object' && x !== null) {
        if (x.type === 'eom') {
            return 'EOM';
        } else if (x.type === 'req') {
            return 'REQ';
        } else if (x.type === 'rep') {
            return 'REP';
        } else if (x.type === 'err') {
            return 'ERR';
        } else if (x.type === 'nfy') {
            return 'NFY';
        }
    }
    return JSON.stringify(x);
}

/* Pretty print a number for UI usage.  Types and values should be easy to
 * read and typing should be obvious.  For numbers, support Infinity, NaN,
 * and signed zeroes properly.
 */
function prettyUiNumber(x) {
    if (x === 1 / 0) { return 'Infinity'; }
    if (x === -1 / 0) { return '-Infinity'; }
    if (Number.isNaN(x)) { return 'NaN'; }
    if (x === 0 && 1 / x > 0) { return '0'; }
    if (x === 0 && 1 / x < 0) { return '-0'; }
    return x.toString();
}

/* Pretty print a dvalue string (bytes represented as U+0000...U+00FF)
 * for UI usage.  Try UTF-8 decoding to get a nice Unicode string (JSON
 * encoded) but if that fails, ensure that bytes are encoded transparently.
 * The result is a quoted string with a special quote marker for a "raw"
 * string when UTF-8 decoding fails.  Very long strings are optionally
 * clipped.
 */
function prettyUiString(x, cliplen) {
    var ret;

    if (typeof x !== 'string') {
        throw new Error('invalid input to prettyUiString: ' + typeof x);
    }
    try {
        // Here utf8.decode() is better than decoding using NodeJS buffer
        // operations because we want strict UTF-8 interpretation.
        ret = JSON.stringify(utf8.decode(x));
    } catch (e) {
        // When we fall back to representing bytes, indicate that the string
        // is "raw" with a 'r"' prefix (a somewhat arbitrary convention).
        // U+0022 = ", U+0027 = '
        ret = 'r"' + x.replace(/[\u0022\u0027\u0000-\u001f\u0080-\uffff]/g, function (match) {
            var cp = match.charCodeAt(0);
            return '\\x' + nybbles[(cp >> 4) & 0x0f] + nybbles[cp & 0x0f];
        }) + '"';
    }

    if (cliplen && ret.length > cliplen) {
        ret = ret.substring(0, cliplen) + '...';  // trailing '"' intentionally missing
    }
    return ret;
}

/* Pretty print a dvalue string (bytes represented as U+0000...U+00FF)
 * for UI usage without quotes.
 */
function prettyUiStringUnquoted(x, cliplen) {
    var ret;

    if (typeof x !== 'string') {
        throw new Error('invalid input to prettyUiStringUnquoted: ' + typeof x);
    }

    try {
        // Here utf8.decode() is better than decoding using NodeJS buffer
        // operations because we want strict UTF-8 interpretation.

        // XXX: unprintable characters etc?  In some UI cases we'd want to
        // e.g. escape newlines and in others not.
        ret = utf8.decode(x);
    } catch (e) {
        // For the unquoted version we don't need to escape single or double
        // quotes.
        ret = x.replace(/[\u0000-\u001f\u0080-\uffff]/g, function (match) {
            var cp = match.charCodeAt(0);
            return '\\x' + nybbles[(cp >> 4) & 0x0f] + nybbles[cp & 0x0f];
        });
    }

    if (cliplen && ret.length > cliplen) {
        ret = ret.substring(0, cliplen) + '...';
    }
    return ret;
}

/* Pretty print a dvalue for UI usage.  Everything comes out as a ready-to-use
 * string.
 *
 * XXX: Currently the debug client formats all values for UI use.  A better
 * solution would be to pass values in typed form and let the UI format them,
 * so that styling etc. could take typing into account.
 */
function prettyUiDebugValue(x, cliplen) {
    if (typeof x === 'object' && x !== null) {
        // Note: typeof null === 'object', so null special case explicitly
        if (x.type === 'eom') {
            return 'EOM';
        } else if (x.type === 'req') {
            return 'REQ';
        } else if (x.type === 'rep') {
            return 'REP';
        } else if (x.type === 'err') {
            return 'ERR';
        } else if (x.type === 'nfy') {
            return 'NFY';
        } else if (x.type === 'unused') {
            return 'unused';
        } else if (x.type === 'undefined') {
            return 'undefined';
        } else if (x.type === 'buffer') {
            return '|' + x.data + '|';
        } else if (x.type === 'object') {
            return '[object ' + (dukClassNames[x.class] || ('class ' + x.class)) + ' ' + x.pointer + ']';
        } else if (x.type === 'pointer') {
            return '<pointer ' + x.pointer + '>';
        } else if (x.type === 'lightfunc') {
            return '<lightfunc 0x' + x.flags.toString(16) + ' ' + x.pointer + '>';
        } else if (x.type === 'number') {
            // duk_tval number, any IEEE double
            var tmp = new Buffer(x.data, 'hex');  // decode into hex
            var val = tmp.readDoubleBE(0);        // big endian ieee double
            return prettyUiNumber(val);
        }
    } else if (x === null) {
        return 'null';
    } else if (typeof x === 'boolean') {
        return x ? 'true' : 'false';
    } else if (typeof x === 'string') {
        return prettyUiString(x, cliplen);
    } else if (typeof x === 'number') {
        // Debug protocol integer
        return prettyUiNumber(x);
    }

    // We shouldn't come here, but if we do, JSON is a reasonable default.
    return JSON.stringify(x);
}

/* Pretty print a debugger message given as an array of parsed dvalues.
 * Result should be a pure ASCII one-liner.
 */
function prettyDebugMessage(msg) {
    return msg.map(prettyDebugValue).join(' ');
}

/* Pretty print a debugger command. */
function prettyDebugCommand(cmd) {
    return debugCommandNames[cmd] || String(cmd);
}

/* Decode and normalize source file contents: UTF-8, tabs to 8,
 * CR LF to LF.
 */
function decodeAndNormalizeSource(data) {
    var tmp;
    var lines, line, repl;
    var i, n;
    var j, m;

    try {
        tmp = data.toString('utf8');
    } catch (e) {
        console.log('Failed to UTF-8 decode source file, ignoring: ' + e);
        tmp = String(data);
    }

    lines = tmp.split(/\r?\n/);
    for (i = 0, n = lines.length; i < n; i++) {
        line = lines[i];
        if (/\t/.test(line)) {
            repl = '';
            for (j = 0, m = line.length; j < m; j++) {
                if (line.charAt(j) === '\t') {
                    repl += ' ';
                    while ((repl.length % 8) != 0) {
                        repl += ' ';
                    }
                } else {
                    repl += line.charAt(j);
                }
            }
            lines[i] = repl;
        }
    }

    // XXX: normalize last newline (i.e. force a newline if contents don't
    // end with a newline)?

    return lines.join('\n');
}

/* Token bucket rate limiter for a given callback.  Calling code calls
 * trigger() to request 'cb' to be called, and the rate limiter ensures
 * that 'cb' is not called too often.
 */
function RateLimited(tokens, rate, cb) {
    var _this = this;
    this.maxTokens = tokens;
    this.tokens = this.maxTokens;
    this.rate = rate;
    this.cb = cb;
    this.delayedCb = false;

    // Right now the implementation is setInterval-based, but could also be
    // made timerless.  There are so few rate limited resources that this
    // doesn't matter in practice.

    this.tokenAdder = setInterval(function () {
        if (_this.tokens < _this.maxTokens) {
            _this.tokens++;
        }
        if (_this.delayedCb) {
            _this.delayedCb = false;
            _this.tokens--;
            _this.cb();
        }
    }, this.rate);
}
RateLimited.prototype.trigger = function () {
    if (this.tokens > 0) {
        this.tokens--;
        this.cb();
    } else {
        this.delayedCb = true;
    }
};

/*
 *  Source file manager
 *
 *  Scan the list of search directories for Ecmascript source files and
 *  build an index of them.  Provides a mechanism to find a source file
 *  based on a raw 'fileName' property provided by the debug target, and
 *  to provide a file list for the web UI.
 *
 *  NOTE: it's tempting to do loose matching for filenames, but this does
 *  not work in practice.  Filenames must match 1:1 with the debug target
 *  so that e.g. breakpoints assigned based on filenames found from the
 *  search paths will match 1:1 on the debug target.  If this is not the
 *  case, breakpoints won't work as expected.
 */

function SourceFileManager(directories) {
    this.directories = directories;
    this.extensions = { '.js': true, '.jsm': true };
    this.files;
}

SourceFileManager.prototype.scan = function () {
    var _this = this;
    var fileMap = {};   // absFn -> true
    var files;

    this.directories.forEach(function (dir) {
        console.log('Scanning source files: ' + dir);
        try {
            wrench.readdirSyncRecursive(dir).forEach(function (fn) {
                var absFn = path.normalize(path.join(dir, fn));   // './foo/bar.js' -> 'foo/bar.js'
                var ent;

                if (fs.existsSync(absFn) &&
                    fs.lstatSync(absFn).isFile() &&
                    _this.extensions[path.extname(fn)]) {
                    // We want the fileMap to contain the filename relative to
                    // the search dir root.
                    fileMap[fn] = true;
                }
            });
        } catch (e) {
            console.log('Failed to scan ' + dir + ': ' + e);
        }
    });

    files = Object.keys(fileMap);
    files.sort();
    this.files = files;

    console.log('Found ' + files.length + ' source files in ' + this.directories.length + ' search directories');
};

SourceFileManager.prototype.getFiles = function () {
    return this.files;
};

SourceFileManager.prototype.search = function (fileName) {
    var _this = this;

    // Loose matching is tempting but counterproductive: filenames must
    // match 1:1 between the debug client and the debug target for e.g.
    // breakpoints to work as expected.  Note that a breakpoint may be
    // assigned by selecting a file from a dropdown populated by scanning
    // the filesystem for available sources and there's no way of knowing
    // if the debug target uses the exact same name.

    function tryLookup() {
        var i, fn, data;

        for (i = 0; i < _this.directories.length; i++) {
            fn = path.join(_this.directories[i], fileName);
            if (fs.existsSync(fn) && fs.lstatSync(fn).isFile()) {
                data = fs.readFileSync(fn);             // Raw bytes
                return decodeAndNormalizeSource(data);  // Unicode string
            }
        }
        return null;
    }

    return tryLookup(fileName);
};

/*
 *  Debug protocol parser
 *
 *  The debug protocol parser is an EventEmitter which parses debug messages
 *  from an input stream and emits 'debug-message' events for completed
 *  messages ending in an EOM.  The parser also provides debug dumping, stream
 *  logging functionality, and statistics gathering functionality.
 *
 *  This parser is used to parse both incoming and outgoing messages.  For
 *  outgoing messages the only function is to validate and debug dump the
 *  messages we're about to send.  The downside of dumping at this low level
 *  is that we can't match request and reply/error messages here.
 *
 *  http://www.sitepoint.com/nodejs-events-and-eventemitter/
 */

function DebugProtocolParser(inputStream,
                             protocolVersion,
                             rawDumpFileName,
                             textDumpFileName,
                             textDumpFilePrefix,
                             hexDumpConsolePrefix,
                             textDumpConsolePrefix) {
    var _this = this;
    this.inputStream = inputStream;
    this.closed = false;       // stream is closed/broken, don't parse anymore
    this.bytes = 0;
    this.dvalues = 0;
    this.messages = 0;
    this.requests = 0;
    this.prevBytes = 0;
    this.bytesPerSec = 0;
    this.statsTimer = null;
    this.readableNumberValue = true;

    events.EventEmitter.call(this);

    var buf = new Buffer(0);    // accumulate data
    var msg = [];               // accumulated message until EOM
    var versionIdentification;

    var statsInterval = 2000;
    var statsIntervalSec = statsInterval / 1000;
    this.statsTimer = setInterval(function () {
        _this.bytesPerSec = (_this.bytes - _this.prevBytes) / statsIntervalSec;
        _this.prevBytes = _this.bytes;
        _this.emit('stats-update');
    }, statsInterval);

    function consume(n) {
        var tmp = new Buffer(buf.length - n);
        buf.copy(tmp, 0, n);
        buf = tmp;
    }

    inputStream.on('data', function (data) {
        var i, n, x, v, gotValue, len, t, tmpbuf, verstr;
        var prettyMsg;

        if (_this.closed || !_this.inputStream) {
            console.log('Ignoring incoming data from closed input stream, len ' + data.length);
            return;
        }

        _this.bytes += data.length;
        if (rawDumpFileName) {
            fs.appendFileSync(rawDumpFileName, data);
        }
        if (hexDumpConsolePrefix) {
            console.log(hexDumpConsolePrefix + data.toString('hex'));
        }

        buf = Buffer.concat([ buf, data ]);

        // Protocol version handling.  When dumping an output stream, the
        // caller gives a non-null protocolVersion so we don't read one here.
        if (protocolVersion == null) {
            if (buf.length > 1024) {
                _this.emit('transport-error', 'Parse error (version identification too long), dropping connection');
                _this.close();
                return;
            }

            for (i = 0, n = buf.length; i < n; i++) {
                if (buf[i] == 0x0a) {
                    tmpbuf = new Buffer(i);
                    buf.copy(tmpbuf, 0, 0, i);
                    consume(i + 1);
                    verstr = tmpbuf.toString('utf-8');
                    t = verstr.split(' ');
                    protocolVersion = Number(t[0]);
                    versionIdentification = verstr;

                    _this.emit('protocol-version', {
                        protocolVersion: protocolVersion,
                        versionIdentification: versionIdentification
                    });
                    break;
                }
            }

            if (protocolVersion == null) {
                // Still waiting for version identification to complete.
                return;
            }
        }

        // Parse complete dvalues (quite inefficient now) by trial parsing.
        // Consume a value only when it's fully present in 'buf'.
        // See doc/debugger.rst for format description.

        while (buf.length > 0) {
            x = buf[0];
            v = undefined;
            gotValue = false;  // used to flag special values like undefined

            if (x >= 0xc0) {
                // 0xc0...0xff: integers 0-16383
                if (buf.length >= 2) {
                    v = ((x - 0xc0) << 8) + buf[1];
                    consume(2);
                }
            } else if (x >= 0x80) {
                // 0x80...0xbf: integers 0-63
                v = x - 0x80;
                consume(1);
            } else if (x >= 0x60) {
                // 0x60...0x7f: strings with length 0-31
                len = x - 0x60;
                if (buf.length >= 1 + len) {
                    v = new Buffer(len);
                    buf.copy(v, 0, 1, 1 + len);
                    v = bufferToDebugString(v);
                    consume(1 + len);
                }
            } else {
                switch (x) {
                case 0x00: v = DVAL_EOM; consume(1); break;
                case 0x01: v = DVAL_REQ; consume(1); break;
                case 0x02: v = DVAL_REP; consume(1); break;
                case 0x03: v = DVAL_ERR; consume(1); break;
                case 0x04: v = DVAL_NFY; consume(1); break;
                case 0x10:  // 4-byte signed integer
                    if (buf.length >= 5) {
                        v = buf.readInt32BE(1);
                        consume(5);
                    }
                    break;
                case 0x11:  // 4-byte string
                    if (buf.length >= 5) {
                        len = buf.readUInt32BE(1);
                        if (buf.length >= 5 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 5, 5 + len);
                            v = bufferToDebugString(v);
                            consume(5 + len);
                        }
                    }
                    break;
                case 0x12:  // 2-byte string
                    if (buf.length >= 3) {
                        len = buf.readUInt16BE(1);
                        if (buf.length >= 3 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 3, 3 + len);
                            v = bufferToDebugString(v);
                            consume(3 + len);
                        }
                    }
                    break;
                case 0x13:  // 4-byte buffer
                    if (buf.length >= 5) {
                        len = buf.readUInt32BE(1);
                        if (buf.length >= 5 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 5, 5 + len);
                            v = { type: 'buffer', data: v.toString('hex') };
                            consume(5 + len);
                            // Value could be a Node.js buffer directly, but
                            // we prefer all dvalues to be JSON compatible
                        }
                    }
                    break;
                case 0x14:  // 2-byte buffer
                    if (buf.length >= 3) {
                        len = buf.readUInt16BE(1);
                        if (buf.length >= 3 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 3, 3 + len);
                            v = { type: 'buffer', data: v.toString('hex') };
                            consume(3 + len);
                            // Value could be a Node.js buffer directly, but
                            // we prefer all dvalues to be JSON compatible
                        }
                    }
                    break;
                case 0x15:  // unused/none
                    v = { type: 'unused' };
                    consume(1);
                    break;
                case 0x16:  // undefined
                    v = { type: 'undefined' };
                    gotValue = true;  // indicate 'v' is actually set
                    consume(1);
                    break;
                case 0x17:  // null
                    v = null;
                    gotValue = true;  // indicate 'v' is actually set
                    consume(1);
                    break;
                case 0x18:  // true
                    v = true;
                    consume(1);
                    break;
                case 0x19:  // false
                    v = false;
                    consume(1);
                    break;
                case 0x1a:  // number (IEEE double), big endian
                    if (buf.length >= 9) {
                        v = new Buffer(8);
                        buf.copy(v, 0, 1, 9);
                        v = { type: 'number', data: v.toString('hex') };

                        if (_this.readableNumberValue) {
                            // The value key should not be used programmatically,
                            // it is just there to make the dumps more readable.
                            v.value = buf.readDoubleBE(1);
                        }
                        consume(9);
                    }
                    break;
                case 0x1b:  // object
                    if (buf.length >= 3) {
                        len = buf[2];
                        if (buf.length >= 3 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 3, 3 + len);
                            v = { type: 'object', 'class': buf[1], pointer: v.toString('hex') };
                            consume(3 + len);
                        }
                    }
                    break;
                case 0x1c:  // pointer
                    if (buf.length >= 2) {
                        len = buf[1];
                        if (buf.length >= 2 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 2, 2 + len);
                            v = { type: 'pointer', pointer: v.toString('hex') };
                            consume(2 + len);
                        }
                    }
                    break;
                case 0x1d:  // lightfunc
                    if (buf.length >= 4) {
                        len = buf[3];
                        if (buf.length >= 4 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 4, 4 + len);
                            v = { type: 'lightfunc', flags: buf.readUInt16BE(1), pointer: v.toString('hex') };
                            consume(4 + len);
                        }
                    }
                    break;
                case 0x1e:  // heapptr
                    if (buf.length >= 2) {
                        len = buf[1];
                        if (buf.length >= 2 + len) {
                            v = new Buffer(len);
                            buf.copy(v, 0, 2, 2 + len);
                            v = { type: 'heapptr', pointer: v.toString('hex') };
                            consume(2 + len);
                        }
                    }
                    break;
                default:
                    _this.emit('transport-error', 'Parse error, dropping connection');
                    _this.close();
                }
            }

            if (typeof v === 'undefined' && !gotValue) {
                break;
            }
            msg.push(v);
            _this.dvalues++;

            // Could emit a 'debug-value' event here, but that's not necessary
            // because the receiver will just collect statistics which can also
            // be done using the finished message.

            if (v === DVAL_EOM) {
                _this.messages++;

                if (textDumpFileName || textDumpConsolePrefix) {
                    prettyMsg = prettyDebugMessage(msg);
                    if (textDumpFileName) {
                        fs.appendFileSync(textDumpFileName, (textDumpFilePrefix || '') + prettyMsg + '\n');
                    }
                    if (textDumpConsolePrefix) {
                        console.log(textDumpConsolePrefix + prettyMsg);
                    }
                }

                _this.emit('debug-message', msg);
                msg = [];  // new object, old may be in circulation for a while
            }
        }
    });

    // Not all streams will emit this.
    inputStream.on('error', function (err) {
        _this.emit('transport-error', err);
        _this.close();
    });

    // Not all streams will emit this.
    inputStream.on('close', function () {
        _this.close();
    });
}
DebugProtocolParser.prototype = Object.create(events.EventEmitter.prototype);

DebugProtocolParser.prototype.close = function () {
    // Although the underlying transport may not have a close() or destroy()
    // method or even a 'close' event, this method is always available and
    // will generate a 'transport-close'.
    //
    // The caller is responsible for closing the underlying stream if that
    // is necessary.

    if (this.closed) { return; }

    this.closed = true;
    if (this.statsTimer) {
        clearInterval(this.statsTimer);
        this.statsTimer = null;
    }
    this.emit('transport-close');
};

/*
 *  Debugger output formatting
 */

function formatDebugValue(v) {
    var buf, dec, len;

    // See doc/debugger.rst for format description.

    if (typeof v === 'object' && v !== null) {
        // Note: typeof null === 'object', so null special case explicitly
        if (v.type === 'eom') {
            return new Buffer([ 0x00 ]);
        } else if (v.type === 'req') {
            return new Buffer([ 0x01 ]);
        } else if (v.type === 'rep') {
            return new Buffer([ 0x02 ]);
        } else if (v.type === 'err') {
            return new Buffer([ 0x03 ]);
        } else if (v.type === 'nfy') {
            return new Buffer([ 0x04 ]);
        } else if (v.type === 'unused') {
            return new Buffer([ 0x15 ]);
        } else if (v.type === 'undefined') {
            return new Buffer([ 0x16 ]);
        } else if (v.type === 'number') {
            dec = new Buffer(v.data, 'hex');
            len = dec.length;
            if (len !== 8) {
                throw new TypeError('value cannot be converted to dvalue: ' + JSON.stringify(v));
            }
            buf = new Buffer(1 + len);
            buf[0] = 0x1a;
            dec.copy(buf, 1);
            return buf;
        } else if (v.type === 'buffer') {
            dec = new Buffer(v.data, 'hex');
            len = dec.length;
            if (len <= 0xffff) {
                buf = new Buffer(3 + len);
                buf[0] = 0x14;
                buf[1] = (len >> 8) & 0xff;
                buf[2] = (len >> 0) & 0xff;
                dec.copy(buf, 3);
                return buf;
            } else {
                buf = new Buffer(5 + len);
                buf[0] = 0x13;
                buf[1] = (len >> 24) & 0xff;
                buf[2] = (len >> 16) & 0xff;
                buf[3] = (len >> 8) & 0xff;
                buf[4] = (len >> 0) & 0xff;
                dec.copy(buf, 5);
                return buf;
            }
        } else if (v.type === 'object') {
            dec = new Buffer(v.pointer, 'hex');
            len = dec.length;
            buf = new Buffer(3 + len);
            buf[0] = 0x1b;
            buf[1] = v.class;
            buf[2] = len;
            dec.copy(buf, 3);
            return buf;
        } else if (v.type === 'pointer') {
            dec = new Buffer(v.pointer, 'hex');
            len = dec.length;
            buf = new Buffer(2 + len);
            buf[0] = 0x1c;
            buf[1] = len;
            dec.copy(buf, 2);
            return buf;
        } else if (v.type === 'lightfunc') {
            dec = new Buffer(v.pointer, 'hex');
            len = dec.length;
            buf = new Buffer(4 + len);
            buf[0] = 0x1d;
            buf[1] = (v.flags >> 8) & 0xff;
            buf[2] = v.flags & 0xff;
            buf[3] = len;
            dec.copy(buf, 4);
            return buf;
        } else if (v.type === 'heapptr') {
            dec = new Buffer(v.pointer, 'hex');
            len = dec.length;
            buf = new Buffer(2 + len);
            buf[0] = 0x1e;
            buf[1] = len;
            dec.copy(buf, 2);
            return buf;
        }
    } else if (v === null) {
        return new Buffer([ 0x17 ]);
    } else if (typeof v === 'boolean') {
        return new Buffer([ v ? 0x18 : 0x19 ]);
    } else if (typeof v === 'number') {
        if (Math.floor(v) === v &&     /* whole */
            (v !== 0 || 1 / v > 0) &&  /* not negative zero */
            v >= -0x80000000 && v <= 0x7fffffff) {
            // Represented signed 32-bit integers as plain integers.
            // Debugger code expects this for all fields that are not
            // duk_tval representations (e.g. command numbers and such).
            if (v >= 0x00 && v <= 0x3f) {
                return new Buffer([ 0x80 + v ]);
            } else if (v >= 0x0000 && v <= 0x3fff) {
                return new Buffer([ 0xc0 + (v >> 8), v & 0xff ]);
            } else if (v >= -0x80000000 && v <= 0x7fffffff) {
                return new Buffer([ 0x10,
                                    (v >> 24) & 0xff,
                                    (v >> 16) & 0xff,
                                    (v >> 8) & 0xff,
                                    (v >> 0) & 0xff ]);
            } else {
                throw new Error('internal error when encoding integer to dvalue: ' + v);
            }
        } else {
            // Represent non-integers as IEEE double dvalues
            buf = new Buffer(1 + 8);
            buf[0] = 0x1a;
            buf.writeDoubleBE(v, 1);
            return buf;
        }
    } else if (typeof v === 'string') {
        if (v.length < 0 || v.length > 0xffffffff) {
            // Not possible in practice.
            throw new TypeError('cannot convert to dvalue, invalid string length: ' + v.length);
        }
        if (v.length <= 0x1f) {
            buf = new Buffer(1 + v.length);
            buf[0] = 0x60 + v.length;
            writeDebugStringToBuffer(v, buf, 1);
            return buf;
        } else if (v.length <= 0xffff) {
            buf = new Buffer(3 + v.length);
            buf[0] = 0x12;
            buf[1] = (v.length >> 8) & 0xff;
            buf[2] = (v.length >> 0) & 0xff;
            writeDebugStringToBuffer(v, buf, 3);
            return buf;
        } else {
            buf = new Buffer(5 + v.length);
            buf[0] = 0x11;
            buf[1] = (v.length >> 24) & 0xff;
            buf[2] = (v.length >> 16) & 0xff;
            buf[3] = (v.length >> 8) & 0xff;
            buf[4] = (v.length >> 0) & 0xff;
            writeDebugStringToBuffer(v, buf, 5);
            return buf;
        }
    }

    // Shouldn't come here.
    throw new TypeError('value cannot be converted to dvalue: ' + JSON.stringify(v));
}

/*
 *  Debugger implementation
 *
 *  A debugger instance communicates with the debug target and maintains
 *  persistent debug state so that the current state can be resent to the
 *  socket.io client (web UI) if it reconnects.  Whenever the debugger state
 *  is changed an event is generated.  The socket.io handler will listen to
 *  state change events and push the necessary updates to the web UI, often
 *  in a rate limited fashion or using a client pull to ensure the web UI
 *  is not overloaded.
 *
 *  The debugger instance assumes that if the debug protocol connection is
 *  re-established, it is always to the same target.  There is no separate
 *  abstraction for a debugger session.
 */

function Debugger() {
    events.EventEmitter.call(this);

    this.web = null;                      // web UI singleton
    this.targetStream = null;             // transport connection to target
    this.outputPassThroughStream = null;  // dummy passthrough for message dumping
    this.inputParser = null;              // parser for incoming debug messages
    this.outputParser = null;             // parser for outgoing debug messages (stats, dumping)
    this.protocolVersion = null;
    this.dukVersion = null;
    this.dukGitDescribe = null;
    this.targetInfo = null;
    this.attached = false;
    this.handshook = false;
    this.reqQueue = null;
    this.stats = {                        // stats for current debug connection
        rxBytes: 0, rxDvalues: 0, rxMessages: 0, rxBytesPerSec: 0,
        txBytes: 0, txDvalues: 0, txMessages: 0, txBytesPerSec: 0
    };
    this.execStatus = {
        attached: false,
        state: 'detached',
        fileName: '',
        funcName: '',
        line: 0,
        pc: 0
    };
    this.breakpoints = [];
    this.callstack = [];
    this.locals = [];
    this.messageLines = [];
    this.messageScrollBack = 100;
}
Debugger.prototype = events.EventEmitter.prototype;

Debugger.prototype.decodeBytecodeFromBuffer = function (buf, consts, funcs) {
    var i, j, n, m, ins, pc;
    var res = [];
    var op, str, args, comments;

    // XXX: add constants inline to preformatted output (e.g. for strings,
    // add a short escaped snippet as a comment on the line after the
    // compact argument list).

    for (i = 0, n = buf.length; i < n; i += 4) {
        pc = i / 4;

        // shift forces unsigned
        if (this.endianness === 'little') {
            ins = buf.readInt32LE(i) >>> 0;
        } else {
            ins = buf.readInt32BE(i) >>> 0;
        }

        op = dukOpcodes.opcodes[ins & 0x3f];
        if (op.extra) {
            op = dukOpcodes.extra[(ins >> 6) & 0xff];
        }

        args = [];
        comments = [];
        if (op.args) {
            for (j = 0, m = op.args.length; j < m; j++) {
                switch (op.args[j]) {
                case 'A_R':   args.push('r' + ((ins >>> 6) & 0xff)); break;
                case 'A_RI':  args.push('r' + ((ins >>> 6) & 0xff) + '(indirect)'); break;
                case 'A_C':   args.push('c' + ((ins >>> 6) & 0xff)); break;
                case 'A_H':   args.push('0x' + ((ins >>> 6) & 0xff).toString(16)); break;
                case 'A_I':   args.push(((ins >>> 6) & 0xff).toString(10)); break;
                case 'A_B':   args.push(((ins >>> 6) & 0xff) ? 'true' : 'false'); break;
                case 'B_RC':  args.push((ins & (1 << 22) ? 'c' : 'r') + ((ins >>> 14) & 0x0ff)); break;
                case 'B_R':   args.push('r' + ((ins >>> 14) & 0x1ff)); break;
                case 'B_RI':  args.push('r' + ((ins >>> 14) & 0x1ff) + '(indirect)'); break;
                case 'B_C':   args.push('c' + ((ins >>> 14) & 0x1ff)); break;
                case 'B_H':   args.push('0x' + ((ins >>> 14) & 0x1ff).toString(16)); break;
                case 'B_I':   args.push(((ins >>> 14) & 0x1ff).toString(10)); break;
                case 'C_RC':  args.push((ins & (1 << 31) ? 'c' : 'r') + ((ins >>> 23) & 0x0ff)); break;
                case 'C_R':   args.push('r' + ((ins >>> 23) & 0x1ff)); break;
                case 'C_RI':  args.push('r' + ((ins >>> 23) & 0x1ff) + '(indirect)'); break;
                case 'C_C':   args.push('c' + ((ins >>> 23) & 0x1ff)); break;
                case 'C_H':   args.push('0x' + ((ins >>> 23) & 0x1ff).toString(16)); break;
                case 'C_I':   args.push(((ins >>> 23) & 0x1ff).toString(10)); break;
                case 'BC_R':  args.push('r' + ((ins >>> 14) & 0x3ffff)); break;
                case 'BC_C':  args.push('c' + ((ins >>> 14) & 0x3ffff)); break;
                case 'BC_H':  args.push('0x' + ((ins >>> 14) & 0x3ffff).toString(16)); break;
                case 'BC_I':  args.push(((ins >>> 14) & 0x3ffff).toString(10)); break;
                case 'ABC_H': args.push(((ins >>> 6) & 0x03ffffff).toString(16)); break;
                case 'ABC_I': args.push(((ins >>> 6) & 0x03ffffff).toString(10)); break;
                case 'BC_LDINT': args.push(((ins >>> 14) & 0x3ffff) - (1 << 17)); break;
                case 'BC_LDINTX': args.push(((ins >>> 14) & 0x3ffff) - 0); break;  // no bias in LDINTX
                case 'ABC_JUMP': {
                    var pc_add = ((ins >>> 6) & 0x03ffffff) - (1 << 25) + 1;  // pc is preincremented before adding
                    var pc_dst = pc + pc_add;
                    args.push(pc_dst + ' (' + (pc_add >= 0 ? '+' : '') + pc_add + ')');
                    break;
                }
                default:      args.push('?'); break;
                }
            }
        }
        if (op.flags) {
            for (j = 0, m = op.flags.length; j < m; j++) {
                if (ins & op.flags[j].mask) {
                    comments.push(op.flags[j].name);
                }
            }
        }

        if (args.length > 0) {
            str = sprintf('%05d %08x   %-10s %s', pc, ins, op.name, args.join(', '));
        } else {
            str = sprintf('%05d %08x   %-10s', pc, ins, op.name);
        }
        if (comments.length > 0) {
            str = sprintf('%-44s ; %s', str, comments.join(', '));
        }

        res.push({
            str: str,
            ins: ins
        });
    }

    return res;
};

Debugger.prototype.uiMessage = function (type, val) {
    var msg;
    if (typeof type === 'object') {
        msg = type;
    } else if (typeof type === 'string') {
        msg = { type: type, message: val };
    } else {
        throw new TypeError('invalid ui message: ' + type);
    }
    this.messageLines.push(msg);
    while (this.messageLines.length > this.messageScrollBack) {
        this.messageLines.shift();
    }
    this.emit('ui-message-update');  // just trigger a sync, gets rate limited
};

Debugger.prototype.sendRequest = function (msg) {
    var _this = this;
    return new Promise(function (resolve, reject) {
        var dvals = [];
        var dval;
        var data;
        var i;

        if (!_this.attached || !_this.handshook || !_this.reqQueue || !_this.targetStream) {
            throw new Error('invalid state for sendRequest');
        }

        for (i = 0; i < msg.length; i++) {
            try {
                dval = formatDebugValue(msg[i]);
            } catch (e) {
                console.log('Failed to format dvalue, dropping connection: ' + e);
                console.log(e.stack || e);
                _this.targetStream.destroy();
                throw new Error('failed to format dvalue');
            }
            dvals.push(dval);
        }

        data = Buffer.concat(dvals);

        _this.targetStream.write(data);
        _this.outputPassThroughStream.write(data);  // stats and dumping

        if (optLogMessages) {
            console.log('Request ' + prettyDebugCommand(msg[1]) + ': ' + prettyDebugMessage(msg));
        }

        if (!_this.reqQueue) {
            throw new Error('no reqQueue');
        }

        _this.reqQueue.push({
            reqMsg: msg,
            reqCmd: msg[1],
            resolveCb: resolve,
            rejectCb: reject
        });
    });
};

Debugger.prototype.sendBasicInfoRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_BASICINFO, DVAL_EOM ]).then(function (msg) {
        _this.dukVersion = msg[1];
        _this.dukGitDescribe = msg[2];
        _this.targetInfo = msg[3];
        _this.endianness = { 1: 'little', 2: 'mixed', 3: 'big' }[msg[4]] || 'unknown';
        _this.emit('basic-info-update');
        return msg;
    });
};

Debugger.prototype.sendGetVarRequest = function (varname, level) {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_GETVAR, varname, (typeof level === 'number' ? level : -1), DVAL_EOM ]).then(function (msg) {
        return { found: msg[1] === 1, value: msg[2] };
    });
};

Debugger.prototype.sendPutVarRequest = function (varname, varvalue, level) {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_PUTVAR, varname, varvalue, (typeof level === 'number' ? level : -1), DVAL_EOM ]);
};

Debugger.prototype.sendInvalidCommandTestRequest = function () {
    // Intentional invalid command
    var _this = this;
    return this.sendRequest([ DVAL_REQ, 0xdeadbeef, DVAL_EOM ]);
};

Debugger.prototype.sendStatusRequest = function () {
    // Send a status request to trigger a status notify, result is ignored:
    // target sends a status notify instead of a meaningful reply
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_TRIGGERSTATUS, DVAL_EOM ]);
};

Debugger.prototype.sendBreakpointListRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_LISTBREAK, DVAL_EOM ]).then(function (msg) {
        var i, n;
        var breakpts = [];

        for (i = 1, n = msg.length - 1; i < n; i += 2) {
            breakpts.push({ fileName: msg[i], lineNumber: msg[i + 1] });
        }

        _this.breakpoints = breakpts;
        _this.emit('breakpoints-update');
        return msg;
    });
};

Debugger.prototype.sendGetLocalsRequest = function (level) {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_GETLOCALS, (typeof level === 'number' ? level : -1), DVAL_EOM ]).then(function (msg) {
        var i;
        var locals = [];

        for (i = 1; i <= msg.length - 2; i += 2) {
            // XXX: do pretty printing in debug client for now
            locals.push({ key: msg[i], value: prettyUiDebugValue(msg[i + 1], LOCALS_CLIPLEN) });
        }

        _this.locals = locals;
        _this.emit('locals-update');
        return msg;
    });
};

Debugger.prototype.sendGetCallStackRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_GETCALLSTACK, DVAL_EOM ]).then(function (msg) {
        var i;
        var stack = [];

        for (i = 1; i + 3 <= msg.length - 1; i += 4) {
            stack.push({
                fileName: msg[i],
                funcName: msg[i + 1],
                lineNumber: msg[i + 2],
                pc: msg[i + 3]
            });
        }

        _this.callstack = stack;
        _this.emit('callstack-update');
        return msg;
    });
};

Debugger.prototype.sendStepIntoRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_STEPINTO, DVAL_EOM ]);
};

Debugger.prototype.sendStepOverRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_STEPOVER, DVAL_EOM ]);
};

Debugger.prototype.sendStepOutRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_STEPOUT, DVAL_EOM ]);
};

Debugger.prototype.sendPauseRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_PAUSE, DVAL_EOM ]);
};

Debugger.prototype.sendResumeRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_RESUME, DVAL_EOM ]);
};

Debugger.prototype.sendEvalRequest = function (evalInput, level) {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_EVAL, evalInput, (typeof level === 'number' ? level : -1), DVAL_EOM ]).then(function (msg) {
        return { error: msg[1] === 1 /*error*/, value: msg[2] };
    });
};

Debugger.prototype.sendDetachRequest = function () {
    var _this = this;
    return this.sendRequest([ DVAL_REQ, CMD_DETACH, DVAL_EOM ]);
};

Debugger.prototype.sendDumpHeapRequest = function () {
    var _this = this;

    return this.sendRequest([ DVAL_REQ, CMD_DUMPHEAP, DVAL_EOM ]).then(function (msg) {
        var res = {};
        var objs = [];
        var i, j, n, m, o, prop;

        res.type = 'heapDump';
        res.heapObjects = objs;

        for (i = 1, n = msg.length - 1; i < n; /*nop*/) {
            o = {};
            o.ptr = msg[i++];
            o.type = msg[i++];
            o.flags = msg[i++] >>> 0;  /* unsigned */
            o.refc = msg[i++];

            if (o.type === DUK_HTYPE_STRING) {
                o.blen = msg[i++];
                o.clen = msg[i++];
                o.hash = msg[i++] >>> 0;  /* unsigned */
                o.data = msg[i++];
            } else if (o.type === DUK_HTYPE_BUFFER) {
                o.len = msg[i++];
                o.data = msg[i++];
            } else if (o.type === DUK_HTYPE_OBJECT) {
                o['class'] = msg[i++];
                o.proto = msg[i++];
                o.esize = msg[i++];
                o.enext = msg[i++];
                o.asize = msg[i++];
                o.hsize = msg[i++];
                o.props = [];
                for (j = 0, m = o.enext; j < m; j++) {
                    prop = {};
                    prop.flags = msg[i++];
                    prop.key = msg[i++];
                    prop.accessor = (msg[i++] == 1);
                    if (prop.accessor) {
                        prop.getter = msg[i++];
                        prop.setter = msg[i++];
                    } else {
                        prop.value = msg[i++];
                    }
                    o.props.push(prop);
                }
                o.array = [];
                for (j = 0, m = o.asize; j < m; j++) {
                    prop = {};
                    prop.value = msg[i++];
                    o.array.push(prop);
                }
            } else {
                console.log('invalid htype: ' + o.type + ', disconnect');
                _this.disconnectDebugger();
                throw new Error('invalid htype');
                return;
            }

            objs.push(o);
        }

        return res;
    });
};

Debugger.prototype.sendGetBytecodeRequest = function () {
    var _this = this;

    return this.sendRequest([ DVAL_REQ, CMD_GETBYTECODE, DVAL_EOM ]).then(function (msg) {
        var idx = 1;
        var nconst;
        var nfunc;
        var val;
        var buf;
        var i, n;
        var consts = [];
        var funcs = [];
        var bcode;
        var preformatted;
        var ret;
        var idxPreformattedInstructions;

        //console.log(JSON.stringify(msg));

        nconst = msg[idx++];
        for (i = 0; i < nconst; i++) {
            val = msg[idx++];
            consts.push(val);
        }

        nfunc = msg[idx++];
        for (i = 0; i < nfunc; i++) {
            val = msg[idx++];
            funcs.push(val);
        }
        val = msg[idx++];

        // Right now bytecode is a string containing a direct dump of the
        // bytecode in target endianness.  Decode here so that the web UI
        // doesn't need to.

        buf = new Buffer(val.length);
        writeDebugStringToBuffer(val, buf, 0);
        bcode = _this.decodeBytecodeFromBuffer(buf, consts, funcs);

        preformatted = [];
        consts.forEach(function (v, i) {
            preformatted.push('; c' + i + ' ' + JSON.stringify(v));
        });
        preformatted.push('');
        idxPreformattedInstructions = preformatted.length;
        bcode.forEach(function (v) {
            preformatted.push(v.str);
        });
        preformatted = preformatted.join('\n') + '\n';

        ret = {
            constants: consts,
            functions: funcs,
            bytecode: bcode,
            preformatted: preformatted,
            idxPreformattedInstructions: idxPreformattedInstructions
        };

        return ret;
    });
};

Debugger.prototype.changeBreakpoint = function (fileName, lineNumber, mode) {
    var _this = this;

    return this.sendRequest([ DVAL_REQ, CMD_LISTBREAK, DVAL_EOM ]).then(function (msg) {
        var i, n;
        var breakpts = [];
        var deleted = false;

        // Up-to-date list of breakpoints on target
        for (i = 1, n = msg.length - 1; i < n; i += 2) {
            breakpts.push({ fileName: msg[i], lineNumber: msg[i + 1] });
        }

        // Delete matching breakpoints in reverse order so that indices
        // remain valid.  We do this for all operations so that duplicates
        // are eliminated if present.
        for (i = breakpts.length - 1; i >= 0; i--) {
            var bp = breakpts[i];
            if (mode === 'deleteall' || (bp.fileName === fileName && bp.lineNumber === lineNumber)) {
                deleted = true;
                _this.sendRequest([ DVAL_REQ, CMD_DELBREAK, i, DVAL_EOM ], function (msg) {
                    // nop
                }, function (err) {
                    // nop
                });
            }
        }

        // Technically we should wait for each delbreak reply but because
        // target processes the requests in order, it doesn't matter.
        if ((mode === 'add') || (mode === 'toggle' && !deleted)) {
            _this.sendRequest([ DVAL_REQ, CMD_ADDBREAK, fileName, lineNumber, DVAL_EOM ], function (msg) {
                // nop
            }, function (err) {
                _this.uiMessage('debugger-info', 'Failed to add breakpoint: ' + err);
            });
        }

        // Read final, effective breakpoints from the target
        _this.sendBreakpointListRequest();
    });
};

Debugger.prototype.disconnectDebugger = function () {
    if (this.targetStream) {
        // We require a destroy() method from the actual target stream
        this.targetStream.destroy();
        this.targetStream = null;
    }
    if (this.inputParser) {
        this.inputParser.close();
        this.inputParser = null;
    }
    if (this.outputPassThroughStream) {
        // There is no close() or destroy() for a passthrough stream, so just
        // close the outputParser which will cancel timers etc.
    }
    if (this.outputParser) {
        this.outputParser.close();
        this.outputParser = null;
    }

    this.attached = false;
    this.handshook = false;
    this.reqQueue = null;
    this.execStatus = {
        attached: false,
        state: 'detached',
        fileName: '',
        funcName: '',
        line: 0,
        pc: 0
    };
};

Debugger.prototype.connectDebugger = function () {
    var _this = this;

    this.disconnectDebugger();  // close previous target connection

    // CUSTOMTRANSPORT: to use a custom transport, change this.targetStream to
    // use your custom transport.

    console.log('Connecting to ' + optTargetHost + ':' + optTargetPort + '...');
    this.targetStream = new net.Socket();
    this.targetStream.connect(optTargetPort, optTargetHost, function () {
        console.log('Debug transport connected');
        _this.attached = true;
        _this.reqQueue = [];
        _this.uiMessage('debugger-info', 'Debug transport connected');
    });

    this.inputParser = new DebugProtocolParser(
        this.targetStream,
        null,
        optDumpDebugRead,
        optDumpDebugPretty,
        optDumpDebugPretty ? 'Recv: ' : null,
        null,
        null   // console logging is done at a higher level to match request/response
    );

    // Use a PassThrough stream to debug dump and get stats for output messages.
    // Simply write outgoing data to both the targetStream and this passthrough
    // separately.
    this.outputPassThroughStream = stream.PassThrough();
    this.outputParser = new DebugProtocolParser(
        this.outputPassThroughStream,
        1,
        optDumpDebugWrite,
        optDumpDebugPretty,
        optDumpDebugPretty ? 'Send: ' : null,
        null,
        null   // console logging is done at a higher level to match request/response
    );

    this.inputParser.on('transport-close', function () {
        _this.uiMessage('debugger-info', 'Debug transport closed');
        _this.disconnectDebugger();
        _this.emit('exec-status-update');
        _this.emit('detached');
    });

    this.inputParser.on('transport-error', function (err) {
        _this.uiMessage('debugger-info', 'Debug transport error: ' + err);
        _this.disconnectDebugger();
    });

    this.inputParser.on('protocol-version', function (msg) {
        var ver = msg.protocolVersion;
        console.log('Debug version identification:', msg.versionIdentification);
        _this.protocolVersion = ver;
        _this.uiMessage('debugger-info', 'Debug version identification: ' + msg.versionIdentification);
        if (ver !== 1) {
            _this.uiMessage('debugger-info', 'Protocol version ' + ver + ' unsupported, dropping connection');
            _this.targetStream.destroy();
        } else {
            _this.uiMessage('debugger-info', 'Debug protocol version: ' + ver);
            _this.handshook = true;
            _this.execStatus = {
                attached: true,
                state: 'attached',
                fileName: '',
                funcName: '',
                line: 0,
                pc: 0
            };
            _this.emit('exec-status-update');
            _this.emit('attached');  // inform web UI

            // Fetch basic info right away
            _this.sendBasicInfoRequest();
        }
    });

    this.inputParser.on('debug-message', function (msg) {
        _this.processDebugMessage(msg);
    });

    this.inputParser.on('stats-update', function () {
        _this.stats.rxBytes = this.bytes;
        _this.stats.rxDvalues = this.dvalues;
        _this.stats.rxMessages = this.messages;
        _this.stats.rxBytesPerSec = this.bytesPerSec;
        _this.emit('debug-stats-update');
    });

    this.outputParser.on('stats-update', function () {
        _this.stats.txBytes = this.bytes;
        _this.stats.txDvalues = this.dvalues;
        _this.stats.txMessages = this.messages;
        _this.stats.txBytesPerSec = this.bytesPerSec;
        _this.emit('debug-stats-update');
    });
};

Debugger.prototype.processDebugMessage = function (msg) {
    var req;
    var prevState, newState;
    var err;

    if (msg[0] === DVAL_REQ) {
        // No actual requests sent by the target right now (just notifys).
        console.log('Unsolicited reply message, dropping connection: ' + prettyDebugMessage(msg));
    } else if (msg[0] === DVAL_REP) {
        if (this.reqQueue.length <= 0) {
            console.log('Unsolicited reply message, dropping connection: ' + prettyDebugMessage(msg));
            this.targetStream.destroy();
        }
        req = this.reqQueue.shift();

        if (optLogMessages) {
            console.log('Reply for ' + prettyDebugCommand(req.reqCmd) + ': ' + prettyDebugMessage(msg));
        }

        if (req.resolveCb) {
            req.resolveCb(msg);
        } else {
            // nop: no callback
        }
    } else if (msg[0] === DVAL_ERR) {
        if (this.reqQueue.length <= 0) {
            console.log('Unsolicited error message, dropping connection: ' + prettyDebugMessage(msg));
            this.targetStream.destroy();
        }
        err = new Error(String(msg[2]) + ' (code ' + String(msg[1]) + ')');
        err.errorCode = msg[1] || 0;
        req = this.reqQueue.shift();

        if (optLogMessages) {
            console.log('Error for ' + prettyDebugCommand(req.reqCmd) + ': ' + prettyDebugMessage(msg));
        }

        if (req.rejectCb) {
            req.rejectCb(err);
        } else {
            // nop: no callback
        }
    } else if (msg[0] === DVAL_NFY) {
        if (optLogMessages) {
            console.log('Notify ' + prettyDebugCommand(msg[1]) + ': ' + prettyDebugMessage(msg));
        }

        if (msg[1] === CMD_STATUS) {
            prevState = this.execStatus.state;
            newState = msg[2] === 0 ? 'running' : 'paused';
            this.execStatus = {
                attached: true,
                state: newState,
                fileName: msg[3],
                funcName: msg[4],
                line: msg[5],
                pc: msg[6]
            };

            if (prevState !== newState && newState === 'paused') {
                // update run state now that we're paused
                this.sendBreakpointListRequest();
                this.sendGetLocalsRequest();
                this.sendGetCallStackRequest();
            }

            this.emit('exec-status-update');
        } else if (msg[1] === CMD_PRINT) {
            this.uiMessage('print', prettyUiStringUnquoted(msg[2], UI_MESSAGE_CLIPLEN));
        } else if (msg[1] === CMD_ALERT) {
            this.uiMessage('alert', prettyUiStringUnquoted(msg[2], UI_MESSAGE_CLIPLEN));
        } else if (msg[1] === CMD_LOG) {
            this.uiMessage({ type: 'log', level: msg[2], message: prettyUiStringUnquoted(msg[3], UI_MESSAGE_CLIPLEN) });
        } else if (msg[1] === CMD_THROW) {
            this.uiMessage({ type: 'throw', fatal: msg[2], message: (msg[2] ? 'UNCAUGHT: ' : 'THROW: ') + prettyUiStringUnquoted(msg[3], UI_MESSAGE_CLIPLEN), fileName: msg[4], lineNumber: msg[5] });
        } else if (msg[1] === CMD_DETACHING) {
            this.uiMessage({ type: 'detaching', reason: msg[2], message: 'DETACH: ' + (msg.length >= 5 ? prettyUiStringUnquoted(msg[3]) : 'detaching') });
        } else {
            // Ignore unknown notify messages
            console.log('Unknown notify, ignoring: ' + prettyDebugMessage(msg));

            //this.targetStream.destroy();
        }
    } else {
        console.log('Invalid initial dvalue, dropping connection: ' + prettyDebugMessage(msg));
        this.targetStream.destroy();
    }
};

Debugger.prototype.run = function () {
    var _this = this;

    // Initial debugger connection

    this.connectDebugger();

    // Poll various state items when running

    var sendRound = 0;
    var statusPending = false;
    var bplistPending = false;
    var localsPending = false;
    var callStackPending = false;

    setInterval(function () {
        if (_this.execStatus.state !== 'running') {
            return;
        }

        // Could also check for an empty request queue, but that's probably
        // too strict?

        // Pending flags are used to avoid requesting the same thing twice
        // while a previous request is pending.  The flag-based approach is
        // quite awkward.  Rework to use promises.

        switch (sendRound) {
        case 0:
            if (!statusPending) {
                statusPending = true;
                _this.sendStatusRequest().finally(function () { statusPending = false; });
            }
            break;
        case 1:
            if (!bplistPending) {
                bplistPending = true;
                _this.sendBreakpointListRequest().finally(function () { bplistPending = false; });
            }
            break;
        case 2:
            if (!localsPending) {
                localsPending = true;
                _this.sendGetLocalsRequest().finally(function () { localsPending = false; });
            }
            break;
        case 3:
            if (!callStackPending) {
                callStackPending = true;
                _this.sendGetCallStackRequest().finally(function () { callStackPending = false; });
            }
            break;
        }
        sendRound = (sendRound + 1) % 4;
    }, 500);
};

/*
 *  Express setup and socket.io
 */

function DebugWebServer() {
    this.dbg = null;       // debugger singleton
    this.socket = null;    // current socket (or null)
    this.keepaliveTimer = null;
    this.uiMessageLimiter = null;
    this.cachedJson = {};  // cache to avoid resending identical data
    this.sourceFileManager = new SourceFileManager(optSourceSearchDirs);
    this.sourceFileManager.scan();
}

DebugWebServer.prototype.handleSourcePost = function (req, res) {
    var fileName = req.body && req.body.fileName;
    var fileData;

    console.log('Source request: ' + fileName);

    if (typeof fileName !== 'string') {
        res.status(500).send('invalid request');
        return;
    }
    fileData = this.sourceFileManager.search(fileName, optSourceSearchDirs);
    if (typeof fileData !== 'string') {
        res.status(404).send('not found');
        return;
    }
    res.status(200).send(fileData);  // UTF-8
};

DebugWebServer.prototype.handleSourceListPost = function (req, res) {
    console.log('Source list request');

    var files = this.sourceFileManager.getFiles();
    res.header('Content-Type', 'application/json');
    res.status(200).json(files);
};

DebugWebServer.prototype.handleHeapDumpGet = function (req, res) {
    console.log('Heap dump get');

    this.dbg.sendDumpHeapRequest().then(function (val) {
        res.header('Content-Type', 'application/json');
        //res.status(200).json(val);
        res.status(200).send(JSON.stringify(val, null, 4));
    }).catch(function (err) {
        res.status(500).send('Failed to get heap dump: ' + (err.stack || err));
    });
};

DebugWebServer.prototype.run = function () {
    var _this = this;

    var express = require('express');
    var bodyParser = require('body-parser');
    var app = express();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);

    app.use(bodyParser.json());
    app.post('/source', this.handleSourcePost.bind(this));
    app.post('/sourceList', this.handleSourceListPost.bind(this));
    app.get('/heapDump.json', this.handleHeapDumpGet.bind(this));
    app.use('/', express.static(__dirname + '/static'));

    http.listen(optHttpPort, function () {
        console.log('Listening on *:' + optHttpPort);
    });

    io.on('connection', this.handleNewSocketIoConnection.bind(this));

    this.dbg.on('attached', function () {
        console.log('Debugger attached');
    });

    this.dbg.on('detached', function () {
        console.log('Debugger detached');
    });

    this.dbg.on('debug-stats-update', function () {
        _this.debugStatsLimiter.trigger();
    });

    this.dbg.on('ui-message-update', function () {
        // Explicit rate limiter because this is a source of a lot of traffic.
        _this.uiMessageLimiter.trigger();
    });

    this.dbg.on('basic-info-update', function () {
        _this.emitBasicInfo();
    });

    this.dbg.on('breakpoints-update', function () {
        _this.emitBreakpoints();
    });

    this.dbg.on('exec-status-update', function () {
        // Explicit rate limiter because this is a source of a lot of traffic.
        _this.execStatusLimiter.trigger();
    });

    this.dbg.on('locals-update', function () {
        _this.emitLocals();
    });

    this.dbg.on('callstack-update', function () {
        _this.emitCallStack();
    });

    this.uiMessageLimiter = new RateLimited(10, 1000, this.uiMessageLimiterCallback.bind(this));
    this.execStatusLimiter = new RateLimited(50, 500, this.execStatusLimiterCallback.bind(this));
    this.debugStatsLimiter = new RateLimited(1, 2000, this.debugStatsLimiterCallback.bind(this));

    this.keepaliveTimer = setInterval(this.emitKeepalive.bind(this), 30000);
};

DebugWebServer.prototype.handleNewSocketIoConnection = function (socket) {
    var _this = this;

    console.log('Socket.io connected');
    if (this.socket) {
        console.log('Closing previous socket.io socket');
        this.socket.emit('replaced');
    }
    this.socket = socket;

    this.emitKeepalive();

    socket.on('disconnect', function () {
        console.log('Socket.io disconnected');
        if (_this.socket === socket) {
             _this.socket = null;
        }
    });

    socket.on('keepalive', function (msg) {
        // nop
    });

    socket.on('attach', function (msg) {
        if (_this.dbg.targetStream) {
            console.log('Attach request when debugger already has a connection, ignoring');
        } else {
            _this.dbg.connectDebugger();
        }
    });

    socket.on('detach', function (msg) {
        // Try to detach cleanly, timeout if no response
        Promise.any([
            _this.dbg.sendDetachRequest(),
            Promise.delay(3000)
        ]).finally(function () {
            _this.dbg.disconnectDebugger();
        });
    });

    socket.on('stepinto', function (msg) {
        _this.dbg.sendStepIntoRequest();
    });

    socket.on('stepover', function (msg) {
        _this.dbg.sendStepOverRequest();
    });

    socket.on('stepout', function (msg) {
        _this.dbg.sendStepOutRequest();
    });

    socket.on('pause', function (msg) {
        _this.dbg.sendPauseRequest();
    });

    socket.on('resume', function (msg) {
        _this.dbg.sendResumeRequest();
    });

    socket.on('eval', function (msg) {
        // msg.input is a proper Unicode strings here, and needs to be
        // converted into a protocol string (U+0000...U+00FF).
        var input = stringToDebugString(msg.input);
        _this.dbg.sendEvalRequest(input, msg.level).then(function (v) {
            socket.emit('eval-result', { error: v.error, result: prettyUiDebugValue(v.value, EVAL_CLIPLEN) });
        });

        // An eval call quite possibly changes the local variables so always
        // re-read locals afterwards.  We don't need to wait for Eval to
        // complete here; the requests will pipeline automatically and be
        // executed in order.

        // XXX: move this to the web UI so that the UI can control what
        // locals are listed (or perhaps show locals for all levels with
        // an expandable tree view).
        _this.dbg.sendGetLocalsRequest();
    });

    socket.on('getvar', function (msg) {
        // msg.varname is a proper Unicode strings here, and needs to be
        // converted into a protocol string (U+0000...U+00FF).
        var varname = stringToDebugString(msg.varname);
        _this.dbg.sendGetVarRequest(varname, msg.level)
        .then(function (v) {
            socket.emit('getvar-result', { found: v.found, result: prettyUiDebugValue(v.value, GETVAR_CLIPLEN) });
        });
    });

    socket.on('putvar', function (msg) {
        // msg.varname and msg.varvalue are proper Unicode strings here, they
        // need to be converted into protocol strings (U+0000...U+00FF).
        var varname = stringToDebugString(msg.varname);
        var varvalue = msg.varvalue;

        // varvalue is JSON parsed by the web UI for now, need special string
        // encoding here.
        if (typeof varvalue === 'string') {
            varvalue = stringToDebugString(msg.varvalue);
        }

        _this.dbg.sendPutVarRequest(varname, varvalue, msg.level)
        .then(function (v) {
            console.log('putvar done');  // XXX: signal success to UI?
        });

        // A PutVar call quite possibly changes the local variables so always
        // re-read locals afterwards.  We don't need to wait for PutVar to
        // complete here; the requests will pipeline automatically and be
        // executed in order.

        // XXX: make the client do this?
        _this.dbg.sendGetLocalsRequest();
    });

    socket.on('add-breakpoint', function (msg) {
        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'add');
    });

    socket.on('delete-breakpoint', function (msg) {
        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'delete');
    });

    socket.on('toggle-breakpoint', function (msg) {
        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'toggle');
    });

    socket.on('delete-all-breakpoints', function (msg) {
        _this.dbg.changeBreakpoint(null, null, 'deleteall');
    });

    socket.on('get-bytecode', function (msg) {
        _this.dbg.sendGetBytecodeRequest().then(function (res) {
            socket.emit('bytecode', res);
        });
    });

    // Resend all debugger state for new client
    this.cachedJson = {};  // clear client state cache
    this.emitBasicInfo();
    this.emitStats();
    this.emitExecStatus();
    this.emitUiMessages();
    this.emitBreakpoints();
    this.emitCallStack();
    this.emitLocals();
};

// Check if 'msg' would encode to the same JSON which was previously sent
// to the web client.  The caller then avoid resending unnecessary stuff.
DebugWebServer.prototype.cachedJsonCheck = function (cacheKey, msg) {
    var newJson = JSON.stringify(msg);
    if (this.cachedJson[cacheKey] === newJson) {
        return true;  // cached
    }
    this.cachedJson[cacheKey] = newJson;
    return false;  // not cached, send (cache already updated)
};

DebugWebServer.prototype.uiMessageLimiterCallback = function () {
    this.emitUiMessages();
};

DebugWebServer.prototype.execStatusLimiterCallback = function () {
    this.emitExecStatus();
};

DebugWebServer.prototype.debugStatsLimiterCallback = function () {
    this.emitStats();
};

DebugWebServer.prototype.emitKeepalive = function () {
    if (!this.socket) { return; }

    this.socket.emit('keepalive', { nodeVersion: process.version });
};

DebugWebServer.prototype.emitBasicInfo = function () {
    if (!this.socket) { return; }

    var newMsg = {
        duk_version: this.dbg.dukVersion,
        duk_git_describe: this.dbg.dukGitDescribe,
        target_info: this.dbg.targetInfo,
        endianness: this.dbg.endianness
    };
    if (this.cachedJsonCheck('basic-info', newMsg)) {
        return;
    }
    this.socket.emit('basic-info', newMsg);
};

DebugWebServer.prototype.emitStats = function () {
    if (!this.socket) { return; }

    this.socket.emit('debug-stats', this.dbg.stats);
};

DebugWebServer.prototype.emitExecStatus = function () {
    if (!this.socket) { return; }

    var newMsg = this.dbg.execStatus;
    if (this.cachedJsonCheck('exec-status', newMsg)) {
        return;
    }
    this.socket.emit('exec-status', newMsg);
};

DebugWebServer.prototype.emitUiMessages = function () {
    if (!this.socket) { return; }

    var newMsg = this.dbg.messageLines;
    if (this.cachedJsonCheck('output-lines', newMsg)) {
        return;
    }
    this.socket.emit('output-lines', newMsg);
};

DebugWebServer.prototype.emitBreakpoints = function () {
    if (!this.socket) { return; }

    var newMsg = { breakpoints: this.dbg.breakpoints };
    if (this.cachedJsonCheck('breakpoints', newMsg)) {
        return;
    }
    this.socket.emit('breakpoints', newMsg);
};

DebugWebServer.prototype.emitCallStack = function () {
    if (!this.socket) { return; }

    var newMsg = { callstack: this.dbg.callstack };
    if (this.cachedJsonCheck('callstack', newMsg)) {
        return;
    }
    this.socket.emit('callstack', newMsg);
};

DebugWebServer.prototype.emitLocals = function () {
    if (!this.socket) { return; }

    var newMsg = { locals: this.dbg.locals };
    if (this.cachedJsonCheck('locals', newMsg)) {
        return;
    }
    this.socket.emit('locals', newMsg);
};

/*
 *  JSON debug proxy
 */

function DebugProxy(serverPort) {
    this.serverPort = serverPort;
    this.server = null;
    this.socket = null;
    this.targetStream = null;
    this.inputParser = null;

    // preformatted dvalues
    this.dval_eom = formatDebugValue(DVAL_EOM);
    this.dval_req = formatDebugValue(DVAL_REQ);
    this.dval_rep = formatDebugValue(DVAL_REP);
    this.dval_nfy = formatDebugValue(DVAL_NFY);
    this.dval_err = formatDebugValue(DVAL_ERR);
}

DebugProxy.prototype.determineCommandNumber = function (cmdName, cmdNumber) {
    var ret;
    if (typeof cmdName === 'string') {
        ret = debugCommandNumbers[cmdName];
    } else if (typeof cmdName === 'number') {
        ret = cmdName;
    }
    ret = ret || cmdNumber;
    if (typeof ret !== 'number') {
        throw Error('cannot figure out command number for "' + cmdName + '" (' + cmdNumber + ')');
    }
    return ret;
};

DebugProxy.prototype.commandNumberToString = function (id) {
    return debugCommandNames[id] || String(id);
};

DebugProxy.prototype.formatDvalues = function (args) {
    if (!args) {
        return [];
    }
    return args.map(function (v) {
        return formatDebugValue(v);
    });
};

DebugProxy.prototype.writeJson = function (val) {
    this.socket.write(JSON.stringify(val) + '\n');
};

DebugProxy.prototype.writeJsonSafe = function (val) {
    try {
        this.writeJson(val);
    } catch (e) {
        console.log('Failed to write JSON in writeJsonSafe, ignoring: ' + e);
    }
};

DebugProxy.prototype.disconnectJsonClient = function () {
    if (this.socket) {
        this.socket.destroy();
        this.socket = null;
    }
};

DebugProxy.prototype.disconnectTarget = function () {
    if (this.inputParser) {
        this.inputParser.close();
        this.inputParser = null;
    }
    if (this.targetStream) {
        this.targetStream.destroy();
        this.targetStream = null;
    }
};

DebugProxy.prototype.run = function () {
    var _this = this;

    console.log('Waiting for client connections on port ' + this.serverPort);
    this.server = net.createServer(function (socket) {
        console.log('JSON proxy client connected');

        _this.disconnectJsonClient();
        _this.disconnectTarget();

        // A byline-parser is simple and good enough for now (assume
        // compact JSON with no newlines).
        var socketByline = byline(socket);
        _this.socket = socket;

        socketByline.on('data', function (line) {
            try {
                // console.log('Received json proxy input line: ' + line.toString('utf8'));
                var msg = JSON.parse(line.toString('utf8'));
                var first_dval;
                var args_dvalues = _this.formatDvalues(msg.args);
                var last_dval = _this.dval_eom;
                var cmd;

                if (msg.request) {
                    // "request" can be a string or "true"
                    first_dval = _this.dval_req;
                    cmd = _this.determineCommandNumber(msg.request, msg.command);
                } else if (msg.reply) {
                    first_dval = _this.dval_rep;
                } else if (msg.notify) {
                    // "notify" can be a string or "true"
                    first_dval = _this.dval_nfy;
                    cmd = _this.determineCommandNumber(msg.notify, msg.command);
                } else if (msg.error) {
                    first_dval = _this.dval_err;
                } else {
                    throw new Error('Invalid input JSON message: ' + JSON.stringify(msg));
                }

                _this.targetStream.write(first_dval);
                if (cmd) {
                    _this.targetStream.write(formatDebugValue(cmd));
                }
                args_dvalues.forEach(function (v) {
                    _this.targetStream.write(v);
                });
                _this.targetStream.write(last_dval);
            } catch (e) {
                console.log(e);

                _this.writeJsonSafe({
                    notify: '_Error',
                    args: [ 'Failed to handle input json message: ' + e ]
                });

                _this.disconnectJsonClient();
                _this.disconnectTarget();
            }
        });

        _this.connectToTarget();
    }).listen(this.serverPort);
};

DebugProxy.prototype.connectToTarget = function () {
    var _this = this;

    console.log('Connecting to ' + optTargetHost + ':' + optTargetPort + '...');
    this.targetStream = new net.Socket();
    this.targetStream.connect(optTargetPort, optTargetHost, function () {
        console.log('Debug transport connected');
    });

    this.inputParser = new DebugProtocolParser(
        this.targetStream,
        null,
        optDumpDebugRead,
        optDumpDebugPretty,
        optDumpDebugPretty ? 'Recv: ' : null,
        null,
        null   // console logging is done at a higher level to match request/response
    );

    // Don't add a 'value' key to numbers.
    this.inputParser.readableNumberValue = false;

    this.inputParser.on('transport-close', function () {
        console.log('Debug transport closed');

        _this.writeJsonSafe({
            notify: '_Disconnecting'
        });

        _this.disconnectJsonClient();
        _this.disconnectTarget();
    });

    this.inputParser.on('transport-error', function (err) {
        console.log('Debug transport error', err);

        _this.writeJsonSafe({
            notify: '_Error',
            args: [ String(err) ]
        });
    });

    this.inputParser.on('protocol-version', function (msg) {
        var ver = msg.protocolVersion;
        console.log('Debug version identification:', msg.versionIdentification);

        _this.writeJson({
            notify: '_TargetConnected',
            args: [ msg.versionIdentification ]  // raw identification string
        });

        if (ver !== 1) {
            console.log('Protocol version ' + ver + ' unsupported, dropping connection');
        }
    });

    this.inputParser.on('debug-message', function (msg) {
        var t;

        //console.log(msg);

        if (typeof msg[0] !== 'object' || msg[0] === null) {
            throw new Error('unexpected initial dvalue: ' + msg[0]);
        } else if (msg[0].type === 'eom') {
            throw new Error('unexpected initial dvalue: ' + msg[0]);
        } else if (msg[0].type === 'req') {
            if (typeof msg[1] !== 'number') {
                throw new Error('unexpected request command number: ' + msg[1]);
            }
            t = {
                request: _this.commandNumberToString(msg[1]),
                command: msg[1],
                args: msg.slice(2, msg.length - 1)
            };
            _this.writeJson(t);
        } else if (msg[0].type === 'rep') {
            t = {
                reply: true,
                args: msg.slice(1, msg.length - 1)
            };
            _this.writeJson(t);
        } else if (msg[0].type === 'err') {
            t = {
                error: true,
                args: msg.slice(1, msg.length - 1)
            };
            _this.writeJson(t);
        } else if (msg[0].type === 'nfy') {
            if (typeof msg[1] !== 'number') {
                throw new Error('unexpected notify command number: ' + msg[1]);
            }
            t = {
                notify: _this.commandNumberToString(msg[1]),
                command: msg[1],
                args: msg.slice(2, msg.length - 1)
            };
            _this.writeJson(t);
        } else {
            throw new Error('unexpected initial dvalue: ' + msg[0]);
        }
    });

    this.inputParser.on('stats-update', function () {
    });
};

/*
 *  Command line parsing and initialization
 */

function main() {
    console.log('((o) Duktape debugger');

    // Parse arguments.

    var argv = require('minimist')(process.argv.slice(2));
    //console.dir(argv);
    if (argv['target-host']) {
        optTargetHost = argv['target-host'];
    }
    if (argv['target-port']) {
        optTargetPort = argv['target-port'];
    }
    if (argv['http-port']) {
        optHttpPort = argv['http-port'];
    }
    if (argv['json-proxy-port']) {
        optJsonProxyPort = argv['json-proxy-port'];
    }
    if (argv['json-proxy']) {
        optJsonProxy = argv['json-proxy'];
    }
    if (argv['source-dirs']) {
        optSourceSearchDirs = argv['source-dirs'].split(path.delimiter);
    }
    if (argv['dump-debug-read']) {
        optDumpDebugRead = argv['dump-debug-read'];
    }
    if (argv['dump-debug-write']) {
        optDumpDebugWrite = argv['dump-debug-write'];
    }
    if (argv['dump-debug-pretty']) {
        optDumpDebugPretty = argv['dump-debug-pretty'];
    }
    if (argv['log-messages']) {
        optLogMessages = true;
    }

    // Dump effective options.  Also provides a list of option names.

    console.log('');
    console.log('Effective options:');
    console.log('  --target-host:       ' + optTargetHost);
    console.log('  --target-port:       ' + optTargetPort);
    console.log('  --http-port:         ' + optHttpPort);
    console.log('  --json-proxy-port:   ' + optJsonProxyPort);
    console.log('  --json-proxy:        ' + optJsonProxy);
    console.log('  --source-dirs:       ' + optSourceSearchDirs.join(' '));
    console.log('  --dump-debug-read:   ' + optDumpDebugRead);
    console.log('  --dump-debug-write:  ' + optDumpDebugWrite);
    console.log('  --dump-debug-pretty: ' + optDumpDebugPretty);
    console.log('  --log-messages:      ' + optLogMessages);
    console.log('');

    // Create debugger and web UI singletons, tie them together and
    // start them.

    if (optJsonProxy) {
        console.log('Starting in JSON proxy mode, JSON port: ' + optJsonProxyPort);

        var prx = new DebugProxy(optJsonProxyPort);
        prx.run();
    } else {
        var dbg = new Debugger();
        var web = new DebugWebServer();
        dbg.web = web;
        web.dbg = dbg;
        dbg.run();
        web.run();
    }
}

main();
