(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( this.Data.Stack === undefined ) this.Data.Stack = undefined;
with ( function(){
with ( Data ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Stack module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data';

function Stack ( )
{
    this.length = 0;
}

var proto = Stack.prototype;

proto.pop  = Array.prototype.pop;
proto.push = Array.prototype.push;

proto.peek = function ( )
{
    return this.length > 0
             ?  this[this.length-1]
             :  undefined;
};

proto.isEmpty = function ( )
{
    return this.length == 0;
};

            return {
                Stack: Stack
            };
        }();
    }
}.call(null) ) {
    this.Data.Stack = Stack;
}
}).call(null);
(function(){
with ( function(){

        return function () {
            var VERSION = '0.1.0';
            var NAMESPACE;

Function.prototype.bind = function ( o ) {
    var f = this;
    return function ( ) {
        return f.apply(o, arguments);
    };
};

            return {

            };
        }();
    }.call(null) ) {
}
}).call(null);
(function(){
    if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
    if ( !this.WebBrowser.GUI || (typeof this.WebBrowser.GUI != 'object' && typeof this.WebBrowser.GUI != 'function') ) this.WebBrowser.GUI = new Object();
    if ( !this.WebBrowser.GUI.Event || (typeof this.WebBrowser.GUI.Event != 'object' && typeof this.WebBrowser.GUI.Event != 'function') ) this.WebBrowser.GUI.Event = new Object();
    if ( this.WebBrowser.GUI.Event.attach === undefined ) this.WebBrowser.GUI.Event.attach = undefined;
    if ( this.WebBrowser.GUI.Event.detach === undefined ) this.WebBrowser.GUI.Event.detach = undefined;
with ( function(){
with ( WebBrowser.GUI.Event ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

NAMESPACE = 'WebBrowser.GUI.Event';

var listener_id = 0;
var registry = {};

attach(window, "unload", function(){
    for ( var i in registry ) detach(Number(i));
});

function attach ( element, type, listener, useCapture ) {
    if ( !element || typeof element !== "object" ) {
        throw new TypeError("argument not a element: " + element);
    }
    type = String(type);
    if ( typeof listener !== "function" ) {
        throw new TypeError("argument not a function: " + listener);
    }
    useCapture = Boolean(useCapture);

    function handler ( e ) {
        e = e || window.event;
        if ( !e.stopPropagation ) { // Sets standard properties for IE
            e.target        = e.srcElement;
            e.currentTarget = this;
            e.cancelable    = true;
            e.stopPropagation = function stopPropagation ( ) {
                this.cancelBubble = true;
            };
            var prevent_default = false;
            e.preventDefault = function preventDefault ( ) {
                prevent_default = true;
            };
        }
        var ret_val = listener.call(this, e);
        return prevent_default ? false : ret_val;
    }

    if ( element.addEventListener ) {
        element.addEventListener(type, handler, useCapture);
    } else if ( element.attachEvent ) {
        element.attachEvent("on"+type, handler);
    } else {
        element["on"+type] = handler;
    }

    var id = listener_id++;
    registry[id] = {
        element   : element,
        type      : type,
        listener  : listener,
        useCapture: useCapture,
        handler   : handler
    };
    return id;
}

function detach ( element, type, listener, useCapture ) {
    if ( arguments.length === 1 && typeof element === "number" ) {
        if ( !registry[element] ) return false;
        var reg    = registry[element];
        delete registry[element];
        return detach_aux(reg.element, reg.type, reg.handler, reg.useCapture);
    } else {
        if ( !element || typeof element !== "object" ) {
            throw new TypeError("argument is not an element: " + element);
        }
        type = String(type);
        if ( typeof listener !== "function" ) {
            throw new TypeError("argument is not s function: " + listener);
        }
        useCapture = Boolean(useCapture);
        var ret_val = false;
        for ( var i in registry ) {
            var reg = registry[i];
            if ( reg.element    === element
              && reg.type       === type
              && reg.listener   === listener
              && reg.useCapture === useCapture )
            {
                delete registry[i];
                ret_val = detach_aux(reg.element, reg.type, reg.handler, reg.useCapture) || ret_val;
            }
        }
        return ret_val;
    }
};

function detach_aux ( element, type, listener, useCapture ) {
    return  element.removeEventListener  ?  element.removeEventListener(type, listener, useCapture)  :
            element.detachEvent          ?  element.detachEvent("on"+type, listener)                 :
                                            delete element["on"+type]                                ;
}

            return {
                detach: detach, attach: attach
            };
        }();
    }
}.call(null) ) {
    this.WebBrowser.GUI.Event.detach = detach;
    this.WebBrowser.GUI.Event.attach = attach;
}
}).call(null);

(function(){
    this.GLOBAL = this;
}).call(null);
(function(){
    if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
    if ( this.Math.ToInteger === undefined ) this.Math.ToInteger = undefined;
    if ( this.Math.ToInt32 === undefined ) this.Math.ToInt32 = undefined;
    if ( this.Math.ToUInt32 === undefined ) this.Math.ToUInt32 = undefined;
    if ( this.Math.ToUInt16 === undefined ) this.Math.ToUInt16 = undefined;
with ( function(){
with ( Math ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Math.ToInteger module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Math';

// This module provides functions emulating the integral type
// conversions defined in ECMA-262 3rd.

function ToInteger ( n ) {
    return n < 0 ? ceil(n)
                 : floor(n) || 0;
}

function ToInt32 ( n ) {
    return n | 0;
}

function ToUInt32 ( n ) {
    return n >>> 0;
}

function ToUInt16 ( n ) {
    return n & 0xFFFF;
}

            return {
                ToUInt16: ToUInt16, ToUInt32: ToUInt32, ToInt32: ToInt32, ToInteger: ToInteger
            };
        }();
    }
}.call(null) ) {
    this.Math.ToUInt16 = ToUInt16;
    this.Math.ToUInt32 = ToUInt32;
    this.Math.ToInt32 = ToInt32;
    this.Math.ToInteger = ToInteger;
}
}).call(null);
(function(){
    if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
    if ( !this.WebBrowser.ScriptExecuter || (typeof this.WebBrowser.ScriptExecuter != 'object' && typeof this.WebBrowser.ScriptExecuter != 'function') ) this.WebBrowser.ScriptExecuter = new Object();
    if ( this.WebBrowser.ScriptExecuter.register === undefined ) this.WebBrowser.ScriptExecuter.register = undefined;
    if ( this.WebBrowser.ScriptExecuter.exec === undefined ) this.WebBrowser.ScriptExecuter.exec = undefined;
with ( function(){
with ( WebBrowser.ScriptExecuter ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

NAMESPACE = 'WebBrowser.ScriptExecuter';

var executers    = {};
var default_type = "text/javascript";

function register ( type, exec ) {
    if ( typeof exec != "function" ) throw new TypeError("function required, but got: " + exec);
    executers[String(type).toLowerCase()] = exec;
}

function exec ( ) {
    var metas = document.getElementsByTagName("META");
    for ( var i=0;  i < metas.length;  i++ ) {
        if ( String(metas[i].httpEquiv).match(/^Content-Script-Type$/i) ) {
            default_type = metas[i].content;
        }
    }
    var scripts = document.getElementsByTagName("SCRIPT");
    for ( var i=0;  i < scripts.length;  i++ ) {
        (function( el ){
            setTimeout(function(){ exec_aux(el); }, 0);
        })(scripts[i]);
    }
}

function exec_aux ( el ) {
    var mime = parseMIMEType(el.type ? el.type : default_type);
    if ( executers[mime.type] ) {
        if ( el.src ) {
            var req = createXHR();
            req.open("GET", el.src, true);
            req.onreadystatechange = function ( ) {
                if ( req.readyState == 4 ) rest(req.responseText);
            };
            req.send(null);
        } else {
            rest(el.innerHTML);
        }
    }
    function rest ( source ) {
        el.parentNode.removeChild(el);
        executers[mime.type](source, mime.attr);
    }
}

function createXHR ( ) {
    try {
        return new XMLHttpRequest();
    } catch (_){
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (_){
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
}

var NOT_TSPECIAL  = '[^][()<>@,;:\\\\"/?=\\x00-\\x20]';
var TOKEN         = "(?:" + NOT_TSPECIAL + "+)";
var MIME_TYPE     = "(?:" + TOKEN + "/" + TOKEN + ")";
var QUOTED_STRING = '(?:"[^"]*(?:\\\\.[^"]*)*")';
var VALUE         = "(?:" + TOKEN + "|" + QUOTED_STRING + ")";

function parseMIMEType ( text ) {
    text = String(text);
    var re = new RegExp("^" + MIME_TYPE, "g");
    re.lastIndex = 0;
    var result = re.exec(text);
    if ( !result ) return {type:text.toLowerCase(), attr:{}};
    var type = result[0].toLowerCase();
    var attr = {};
    text = text.substring(re.lastIndex);
    re = new RegExp("^\\s*;\\s*(" + TOKEN + ")\\s*=\\s*(" + VALUE + ")", "g");
    re.lastIndex = 0;
    while ( result = re.exec(text) ) {
        attr[result[1].toLowerCase()] = result[2];
        text = text.substring(re.lastIndex);
        re.lastIndex = 0;
    }
    return {type:type, attr:attr};
}

if ( window.addEventListener ) {
    window.addEventListener("load", exec, false);
} else if ( window.attachEvent ) {
    window.attachEvent("onload", exec);
} else {
    if ( window.onload ) {
        var temp = window.onload;
        window.onload = function ( ) {
            var r = temp.apply(this, arguments);
            exec();
            return r;
        };
    } else {
        window.onload = exec;
    }
}

            return {
                register: register, exec: exec
            };
        }();
    }
}.call(null) ) {
    this.WebBrowser.ScriptExecuter.register = register;
    this.WebBrowser.ScriptExecuter.exec = exec;
}
}).call(null);
(function(){
    if ( !this.JSON || (typeof this.JSON != 'object' && typeof this.JSON != 'function') ) this.JSON = new Object();
    if ( this.JSON.dump === undefined ) this.JSON.dump = undefined;
with ( function(){
with ( JSON ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

NAMESPACE = 'JSON';

var DUMPER = "JSON.dumper";

function dump ( data, opts ) {
    opts = opts || {};
    var indent = String(opts.indent);
    if ( !indent.match(/^\s*$/) ) indent = "  ";
    return dump_main(data, {pretty:opts.pretty, indent:indent, deflate:opts.deflate});
}

function dump_main ( data, opts ) {
    switch ( typeof data ) {
      case "undefined":
        return opts.deflate ? '(void 0)' : '"undefined"';

      case "boolean":
      case "number":
        return String(data);

      case "string":
        return dump_string(data);

      case "function":
      case "object":
        if ( data === null ) {
            return "null";
        } else if ( typeof data[DUMPER] == "function" ){
            return data[DUMPER](opts);
        } else if ( data instanceof Array ) {
            var arr = [];
            for ( var i=0;  i < data.length;  i++ ) arr[i] = dump_main(data[i], opts);
            if ( opts.pretty ) {
                return "[\n" + arr.join(",\n").replace(/^/mg, opts.indent) + "\n]";
            } else {
                return "[" + arr.join(",") + "]";
            }
        } else {
            var arr = [];
            for ( var i in data ) {
                if ( data.hasOwnProperty(i) ) {
                    arr.push(dump_string(i) + ":" + dump_main(data[i], opts));
                }
            }
            if ( opts.pretty ) {
                return "{\n" + arr.join(",\n").replace(/^/mg, opts.indent) + "\n}";
            } else {
                return "{" + arr.join(",") + "}";
            }
        }
    }
}

function dump_string ( str ) {
    return '"' + str.replace(/[^\u0020-\u0021\u0023-\u005B\u005D-\u007E]/g, function (c){
                             // any ASCII character except '"', '\' and control-character
        c = c.charCodeAt(0);
        switch ( c ) {
          case '"' : return '\\"';
          case '\\': return '\\\\';
          case '\b': return '\\b';
          case '\f': return '\\f';
          case '\n': return '\\n';
          case '\r': return '\\r';
          case '\t': return '\\t';
          default:
            c = c.toString(16);
            while ( c.length < 4 ) c = "0" + c;
            return "\\u" + c;
        }
    }) + '"';
}

String.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? "new String(" + dump_string(this.toString()) + ")"
                        : dump_string(this.toString());
};

Boolean.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? "new Boolean(" + this.toString() + ")"
                        : this.toString();
};

Number.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? "new Number(" + this.toString() + ")"
                        : this.toString();
};

Date.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? "new Date(" + this.valueOf() + ")"
                        : dump_string(this.toString());
};

RegExp.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? this.toString()
                        : dump_string(this.toString());
};

Function.prototype[DUMPER] = function ( opts ) {
    return opts.deflate ? this.toString()
                        : dump_string(this.toString());
};

            return {
                dump: dump
            };
        }();
    }
}.call(null) ) {
    this.JSON.dump = dump;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Data.Cons.Cell === undefined ) this.Data.Cons.Cell = undefined;
    if ( this.Data.Cons.Nil === undefined ) this.Data.Cons.Nil = undefined;
    if ( this.Data.Cons.nil === undefined ) this.Data.Cons.nil = undefined;
    if ( this.Data.Cons.cons === undefined ) this.Data.Cons.cons = undefined;
    if ( this.Data.Cons.car === undefined ) this.Data.Cons.car = undefined;
    if ( this.Data.Cons.cdr === undefined ) this.Data.Cons.cdr = undefined;
with ( function(){
with ( Data.Cons ) {

        return function () {
            var VERSION = '0.2.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Cons code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Cons';

function Cell ( car, cdr ) {
    this.car = car;
    this.cdr = cdr;
}

var proto = Cell.prototype;

proto.toString = function ( ) {
    return "(" + this.car + " . " + this.cdr + ")";
};

proto.toLocaleString = function ( ) {
    return "("
         + (this.car == null ? String(this.car) : this.car.toLocaleString)
         + " . "
         + (this.cdr == null ? String(this.cdr) : this.cdr.toLocaleString)
         + ")";
};

proto.isNil = function ( ) {
    return false;
};

function Nil ( ) {
    this.car = this;
    this.cdr = this;
}

var proto = Nil.prototype = new Cell();
proto.constructor = Nil;

proto.toString       =
proto.toLocaleString = function ( ) {
    return "nil";
};

proto.isNil = function ( ) {
    return true;
};

function nil ( ) {
    return new Nil();
};

function cons ( car, cdr ) {
    return new Cell(car, cdr);
}

function car ( cell ) {
    return cell.car;
}

function cdr ( cell ) {
    return cell.cdr;
}

            return {
                nil: nil, Nil: Nil, car: car, Cell: Cell, cdr: cdr, cons: cons
            };
        }();
    }
}.call(null) ) {
    this.Data.Cons.nil = nil;
    this.Data.Cons.Nil = Nil;
    this.Data.Cons.car = car;
    this.Data.Cons.Cell = Cell;
    this.Data.Cons.cdr = cdr;
    this.Data.Cons.cons = cons;
}
}).call(null);
(function(){
    if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
    if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
    if ( this.Util.Arrayize.arrayize === undefined ) this.Util.Arrayize.arrayize = undefined;
with ( function(){
with ( Util.Arrayize ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

NAMESPACE = 'Util.Arrayize';

var slice = Array.prototype.slice;

function arrayize ( o ) {
    if ( !o ) return [];
    try {
        return slice.call(o, 0);
    } catch ( e ) {
        var r = [];
        for ( var i=0;  i < o.length;  i++ ) {
            r[i] = o[i];
        }
        return r;
    }
}

            return {
                arrayize: arrayize
            };
        }();
    }
}.call(null) ) {
    this.Util.Arrayize.arrayize = arrayize;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.Functional.discontinue === undefined ) this.Data.Functional.discontinue = undefined;
    if ( this.Data.Functional.DiscontinueException === undefined ) this.Data.Functional.DiscontinueException = undefined;
    if ( this.Data.Functional.ignore === undefined ) this.Data.Functional.ignore = undefined;
    if ( this.Data.Functional.IgnoreException === undefined ) this.Data.Functional.IgnoreException = undefined;
    if ( this.Data.Functional.return_list === undefined ) this.Data.Functional.return_list = undefined;
    if ( this.Data.Functional.ReturnListException === undefined ) this.Data.Functional.ReturnListException = undefined;
    if ( this.Data.Functional.Loop.EndOfLoopException === undefined ) this.Data.Functional.Loop.EndOfLoopException = undefined;
    if ( this.Data.Functional.Loop.wrap_for_forEach === undefined ) this.Data.Functional.Loop.wrap_for_forEach = undefined;
    if ( this.Data.Functional.Loop.wrap_for_fold === undefined ) this.Data.Functional.Loop.wrap_for_fold = undefined;
    if ( this.Data.Functional.Loop.wrap_for_map === undefined ) this.Data.Functional.Loop.wrap_for_map = undefined;
with ( function(){
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional';

function discontinue ( /* variable arguments */ ) {
    throw new DiscontinueException(arguments);
}

function DiscontinueException ( args ) {
    this.args = args;
}
var proto = DiscontinueException.prototype;
proto.name    = NAMESPACE + ".DiscontinueException";
proto.message = "unusual use of `discontinue' (this should be caught by `forEach' or other iteration-methods).";

function ignore ( /* variable arguments */ ) {
    throw new IgnoreException(arguments);
}

function IgnoreException ( args ) {
    this.args = args;
}
var proto = IgnoreException.prototype;
proto.name    = NAMESPACE + ".IgnoreException";
proto.message = "unusual use of `ignore' (this should be caught by `forEach' or other iteration-methods).";

function return_list ( /* variable arguments */ ) {
    throw new ReturnListException(arguments);
}

function ReturnListException ( args ) {
    this.args = args;
}
var proto = ReturnListException.prototype;
proto.name    = NAMESPACE + ".ReturnListException";
proto.message = "unusual use of `return_list' (this should be caught by `forEach' or other iteration-methods).";

NAMESPACE = 'Data.Functional.Loop';

function EndOfLoopException ( v ) {
    this.result = v;
}
var proto = EndOfLoopException.prototype;
proto.name    = NAMESPACE + ".EndOfLoopException";
proto.message = "this should be caught by `forEach' or other iteration-methods";

function wrap_for_forEach ( t, f ) {
    if ( typeof f != "function" ) throw new TypeError("argument to forEach must be function");
    return function ( v ) {
        try {
            f.call(t, v);
        } catch ( e ) {
            if ( e instanceof DiscontinueException ) {
                throw new EndOfLoopException();
            } else if ( e instanceof IgnoreException ) {
                // Do nothing.
            } else if ( e instanceof ReturnListException ) {
                // Do nothing.
            } else {
                throw e;
            }
        }
    };
}

function wrap_for_fold ( t, f, s ) {
    if ( typeof f != "function" ) throw new TypeError("argument to fold must be function");
    return function ( v ) {
        try {
            return s = f.call(t, s, v);
        } catch ( e ) {
            if ( e instanceof DiscontinueException ) {
                throw new EndOfLoopException(e.args[e.args.length-1]);
            } else if ( e instanceof IgnoreException ) {
                return s;
            } else if ( e instanceof ReturnListException ) {
                return s = f.call(t, s, e.args[e.args.length-1]);
            } else {
                throw e;
            }
        }
    };
}

function wrap_for_map ( t, f, a ) {
    if ( typeof f != "function" ) throw new TypeError("argument to map must be function");
    if ( typeof a != "function" ) throw new TypeError("the third argument to wrap_for_map must be function");
    return function ( v ) {
        try {
            a.call(null, f.call(t, v));
        } catch ( e ) {
            if ( e instanceof DiscontinueException ) {
                a.apply(null, e.args);
                throw new EndOfLoopException();
            } else if ( e instanceof IgnoreException ) {
                // Do nothing.
            } else if ( e instanceof ReturnListException ) {
                a.apply(null, e.args);
            } else {
                throw e;
            }
        }
    };
}

            return {
                DiscontinueException: DiscontinueException, wrap_for_forEach: wrap_for_forEach, wrap_for_map: wrap_for_map, ignore: ignore, discontinue: discontinue, ReturnListException: ReturnListException, wrap_for_fold: wrap_for_fold, return_list: return_list, IgnoreException: IgnoreException, EndOfLoopException: EndOfLoopException
            };
        }();
    }
}
}.call(null) ) {
    this.Data.Functional.DiscontinueException = DiscontinueException;
    this.Data.Functional.Loop.wrap_for_forEach = wrap_for_forEach;
    this.Data.Functional.Loop.wrap_for_map = wrap_for_map;
    this.Data.Functional.ignore = ignore;
    this.Data.Functional.discontinue = discontinue;
    this.Data.Functional.ReturnListException = ReturnListException;
    this.Data.Functional.Loop.wrap_for_fold = wrap_for_fold;
    this.Data.Functional.return_list = return_list;
    this.Data.Functional.IgnoreException = IgnoreException;
    this.Data.Functional.Loop.EndOfLoopException = EndOfLoopException;
}
}).call(null);
(function(){
    if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
    if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
with ( function(){
with ( Util.Arrayize ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

var null_constructor = function (){};

Function.prototype.extend = function extend ( init, props ) {
    if ( typeof init !== "function" ) throw new TypeError("function is expected: " + init);
    if ( props == null ) props = {};

    var SuperClass = this;
    var SubClass = function ( ) {
        var self = this;
        var super_is_called = false;
        function super_call ( ) {
            if ( super_is_called ) throw new Error("super-constructor has already been called");
            super_is_called = true;
            var ret_val = SuperClass.apply(self, arguments);
            if ( ret_val instanceof Object ) {
                for ( var i in ret_val ) {
                    if ( ret_val.hasOwnProperty(i) ) self[i] = ret_val[i];
                }
            }
            return ret_val;
        }
        arguments = arrayize(arguments);
        arguments.unshift(super_call);
        return init.apply(self, arguments);
    };

    null_constructor.prototype = SuperClass.prototype;
    var proto = SubClass.prototype = new null_constructor;
    proto.constructor = SubClass;
    proto.$super = function ( prop ) {
        if ( !arguments.length ) return SuperClass;
        var value = SuperClass.prototype[prop];
        if ( typeof value === "function" ) {
            return value.bind(this);
        } else {
            return value;
        }
    };
    for ( var i in props ) proto[i] = props[i];

    return SubClass;
};

            return {

            };
        }();
    }
}.call(null) ) {
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( this.Data.Error.Error === undefined ) this.Data.Error.Error = undefined;
    if ( this.Data.Error.Exception === undefined ) this.Data.Error.Exception = undefined;
with ( function(){
with ( Data.Error ) {

        return function () {
            var VERSION = '0.3.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Error module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Error';

var Error = GLOBAL.Error.extend(
    function ( $super, message ) {
        $super(message);
    },
    {
        name    : NAMESPACE + ".Error",
        message : "something's wrong",
        toString: function ( ) {
            var s = String(this.message);
            s = s  ?  this.name + ": " + s
                   :  this.name;
            if ( this.fileName ) {
                s += " @" + this.fileName + ":" + this.lineNumber;
            }
            return s;
        }
    }
);

var Exception = GLOBAL.Error.extend(
    function ( $super, message ) {
        $super(message);
    },
    {
        name    : NAMESPACE + ".Exception",
        message : "an exception has occurred",
        toString: function ( ) {
            var s = String(this.message);
            s = s  ?  this.name + ": " + s
                   :  this.name;
            if ( this.fileName ) {
                s += " @" + this.fileName + ":" + this.lineNumber;
            }
            return s;
        }
    }
);

            return {
                Error: Error, Exception: Exception
            };
        }();
    }
}.call(null) ) {
    this.Data.Error.Error = Error;
    this.Data.Error.Exception = Exception;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( this.Data.Error.IllegalStateError === undefined ) this.Data.Error.IllegalStateError = undefined;
with ( function(){
with ( Data.Error ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Error.IllegalStateError module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Error';

var IllegalStateError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".IllegalStateError",
        message: "illegal state"
    }
);

            return {
                IllegalStateError: IllegalStateError
            };
        }();
    }
}.call(null) ) {
    this.Data.Error.IllegalStateError = IllegalStateError;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( this.Data.Error.UnimplementedMethodError === undefined ) this.Data.Error.UnimplementedMethodError = undefined;
with ( function(){
with ( Data.Error ) {

        return function () {
            var VERSION = '0.3.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Error.UnimplementedMethodError.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Error';

var UnimplementedMethodError = Error.extend(
    function ( $super, method, invocant, message ) {
        if ( message !== undefined ) {
            $super(message);
        } else {
            $super("an required method `" + method + "' has not been implemented");
        }
        this.method   = method;
        this.invocant = invocant;
    },
    { name: NAMESPACE + ".UnimplementedMethodError" }
);

            return {
                UnimplementedMethodError: UnimplementedMethodError
            };
        }();
    }
}.call(null) ) {
    this.Data.Error.UnimplementedMethodError = UnimplementedMethodError;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( this.Data.Iterator.NoSuchElementError === undefined ) this.Data.Iterator.NoSuchElementError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

        return function () {
            var VERSION = '0.2.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Iterator code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Iterator';

var NoSuchElementError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".NoSuchElementError",
        message: "no such element"
    }
);

            return {
                NoSuchElementError: NoSuchElementError
            };
        }();
    }
}
}.call(null) ) {
    this.Data.Iterator.NoSuchElementError = NoSuchElementError;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.Functional.Enumerable === undefined ) this.Data.Functional.Enumerable = undefined;
    if ( this.Data.Functional.EmptyEnumerationError === undefined ) this.Data.Functional.EmptyEnumerationError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional';

function Enumerable ( ) {
    // This is a kind of abstract class.
}

var proto = Enumerable.prototype;

var obj_name = "[object " + NAMESPACE + ".Enumerable]";

proto.toString = function ( ) {
    return obj_name;
};

proto.iterator = function ( ) {
    throw new UnimplementedMethodError("iterator", this);
};

proto.forEach = function ( f ) {
    var ret_val;
    f = wrap_for_forEach(this, f);
    for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
        try {
            f(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return;
            else                                   throw e;
        }
    }
};

proto.fold = function ( f, s ) {
    f = wrap_for_fold(this, f, s);
    for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
        try {
            s = f(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return e.result;
            else                                   throw e;
        }
    }
    return s;
};

proto.fold1 = function ( f ) {
    var it = this.iterator();
    if ( it.isTail() ) throw new EmptyEnumerationError();
    var s = it.value();
    it = it.next();
    f = wrap_for_fold(this, f, s);
    for ( ;  !it.isTail();  it=it.next() ) {
        try {
            s = f(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return e.result;
            else                                   throw e;
        }
    }
    return s;
};

proto.and = function ( ) {
    return this.fold(function ( x, y ) {
        return y || discontinue(y);
    }, true);
};

proto.or = function ( ) {
    return this.fold(function ( x, y ) {
        return y && discontinue(y);
    }, false);
};

proto.all = function ( f ) {
    return this.fold(function ( x, y ) {
        y = f.call(this, y);
        return y || discontinue(y);
    }, true);
};

proto.any = function ( f ) {
    return this.fold(function ( x, y ) {
        y = f.call(this, y);
        return y && discontinue(y);
    }, false);
};

var EmptyEnumerationError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".EmptyEnumerationError",
        message: "empty enumeration"
    }
);

            return {
                EmptyEnumerationError: EmptyEnumerationError, Enumerable: Enumerable
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Functional.EmptyEnumerationError = EmptyEnumerationError;
    this.Data.Functional.Enumerable = Enumerable;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( this.Data.Iterator.Iterator === undefined ) this.Data.Iterator.Iterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

        return function () {
            var VERSION = '0.2.1';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Iterator code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Iterator';

function Iterator ( ) {
    // This is a kind of abstract class.
    // Sub-classes should implement appropreate methods.
}

var proto = Iterator.prototype;

var obj_name = "[object " + NAMESPACE + ".Iterator]";

proto.toString = function ( ) {
    return obj_name;
};

// Returns true if this iterator points to the tail of a list,
// false othersise.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.isTail = function ( ) {
    throw new UnimplementedMethodError("isTail", this);
};

// Returns value of the element which is just after the position
// this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method,
// which may throws Data.Iterator.NoSuchElementError.
proto.value = function ( ) {
    throw new UnimplementedMethodError("value", this);
};

// Returns a new iterator that points to the next position to the
// one which this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method,
// which may throws Data.Iterator.NoSuchElementError.
proto.next = function ( ) {
    throw new UnimplementedMethodError("next", this);
};

// Returns true if and only if this iterator is associated with the
// object specified by the argument, false otherwise.
// The default implementation just returns false.
proto.isBoundTo = function ( list ) {
    return false;
};

proto.find = function ( f ) {
    for ( var it=this;  !it.isTail();  it=it.next() ) {
        if ( f(it.value()) ) break;
    }
    return it;
};

            return {
                Iterator: Iterator
            };
        }();
    }
}
}.call(null) ) {
    this.Data.Iterator.Iterator = Iterator;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.Functional.Collection === undefined ) this.Data.Functional.Collection = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional';

function Collection ( ) {
    // This is kind of abstract class.
}

var proto = Collection.prototype = new Enumerable();
proto.constructor = Collection;

var obj_name = "[object " + NAMESPACE + ".Collection]";

proto.toString = function ( ) {
    return obj_name;
};

proto.toArray = function ( ) {
    var a = [];
    this.forEach(function( it ){
        a.push(it);
    });
    return a;
};

proto.add = function ( /* variable args */ ) {
    throw new UnimplementedMethodError("add", this);
};

proto.addAll = function ( /* variable arguments */ ) {
    var self    = this;
    var changed = false;
    for ( var i=0;  i < arguments.length;  i++ ) {
        var c = arguments[i];
        if ( c instanceof Collection ) {
            c.forEach(function( it ){
                changed = self.add(it) || changed;
            });
        } else if ( c instanceof Array ) {
            changed = this.add.apply(this, c) || changed;
        } else {
            chagned = this.add(c) || changed;
        }
    }
    return changed;
};

proto.removeAt = function ( it ) {
    throw new UnimplementedMethodError("removeAt", this);
};

proto.isEmpty = function ( ) {
    return this.iterator().isTail();
};

proto.empty = function ( ) {
    var it;
    while ( !(it=this.iterator()).isTail() ) this.removeAt(it);
};

proto.size = function ( ) {
    var i = 0;
    this.forEach(function(){ ++i; });
    return i;
};

proto.emptyCopy = function ( ) {
    return new this.constructor();
};

proto.copy = function ( ) {
    var c = this.emptyCopy();
    this.forEach(function( it ){
        c.add(it);
    });
    return c;
};

proto.map = function ( f ) {
    var c = this.emptyCopy();
    f = wrap_for_map(this, f, function ( ) {
        c.add.apply(c, arguments);
    });
    for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
        try {
            f(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return c;
            else                                   throw e;
        }
    }
    return c;
};

proto.filter = function ( f ) {
    return this.map(function( it ){
        if ( f.call(this, it) ) return it;
        else                    ignore();
    });
};

proto.grep = function ( re ) {
    if ( !(re instanceof RegExp) ) re = new Regex(re);
    return this.filter(function(it){
        return String(it).match(re);
    });
};

            return {
                Collection: Collection
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Functional.Collection = Collection;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( this.Data.Iterator.BidirectionalIterator === undefined ) this.Data.Iterator.BidirectionalIterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

        return function () {
            var VERSION = '0.2.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Iterator code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Iterator';

function BidirectionalIterator ( ) {
    // This is a kind of abstract class.
    // Sub-classes should implement appropreate methods.
}

var proto = BidirectionalIterator.prototype = new Iterator();
proto.constructor = BidirectionalIterator;

var obj_name = "[object " + NAMESPACE + ".BidirectionalIterator]";

proto.toString = function ( ) {
    return obj_name;
};

// Returns true if this iterator points to the head of a list,
// false othersise.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.isHead = function ( ) {
    throw new UnimplementedMethodError("isHead", this);
};

// Returns a new iterator that points to the previous position to
// the one which this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.previous = function ( ) {
    throw new UnimplementedMethodError("previous", this);
};

            return {
                BidirectionalIterator: BidirectionalIterator
            };
        }();
    }
}
}.call(null) ) {
    this.Data.Iterator.BidirectionalIterator = BidirectionalIterator;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.Functional.Set === undefined ) this.Data.Functional.Set = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.4.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional';

function Set ( ) {
    // This is kind of interface.
}

var proto = Set.prototype = new Collection();
proto.constructor = Set;

var obj_name = "[object " + NAMESPACE + ".Set]";

proto.toString = function ( ) {
    return obj_name;
};

proto.contains = function ( /* variable args */ ) {
    throw new UnimplementedMethodError("contains", this);
};

proto.containsAll = function ( /* variable args */ ) {
    for ( var i=0;  i < arguments.length;  i++ ) {
        var e = arguments[i];
        if ( e instanceof Array ) {
            if ( !this.contains.apply(this, e) ) return false;
        } else if ( e instanceof Collection ) {
            var self = this;
            if ( !e.all(function(it){ return self.contains(it); }) ) return false;
        } else {
            if ( !this.contains(e) ) return false;
        }
    }
    return true;
};

proto.remove = function ( /* variable args */ ) {
    throw new UnimplementedMethodError("remove", this);
};

proto.removeAll = function ( /* variable args */ ) {
    var changed = false;
    for ( var i=0;  i < arguments.length;  i++ ) {
        var e = arguments[i];
        if ( e instanceof Array ) {
            changed = this.remove.apply(this, e) || changed;
        } else if ( e instanceof Collection ) {
            var self = this;
            e.forEach(function( it ){
                changed = self.remove(it) || changed;
            });
        } else {
            changed = this.remove(e) || changed;
        }
    }
    return changed;
};

proto.removeAt = function ( it ) {
    if ( !(it instanceof Iterator) ) throw new TypeError("the argument is not of type Data.Iterator.Iterator");
    if ( !it.isBoundTo(this)       ) throw new IllegalStateError();
    var v = it.value();
    this.remove(v);
    return v;
};

proto.retainAll = function ( /* variable args */ ) {
    var temp = this.emptyCopy();
    temp.addAll.apply(temp, arguments);
    return this.removeAll( this.filter(function(it){
        return !temp.contains(it);
    }) );
};

            return {
                Set: Set
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Functional.Set = Set;
}
}).call(null);
(function(){
    if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.Functional.List === undefined ) this.Data.Functional.List = undefined;
with ( function(){
with ( Math ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// This module should not be required directly.
// Require Data.Functional.List instead.

NAMESPACE = 'Data.Functional';

function List ( ) {
    // This is a kind of abstract class.
}

var proto = List.prototype = new Collection();
proto.constructor = List;

// Iterator methods.
// Return an iterator pointing to just before the n'th element
// (the first element is the 0th one). If there are only n elements
// in this list, return an iterator pointing to the tail.
// If n is negative, it is treated as size+n, where size is the length
// of this list. Thus, if n is negative, the result of head(n) and
// the one of tail(-n) should be equivalent.
// These methods can throw RangeError.
proto.head = function ( n ) {
    if ( n < 0 ) return this.tail(-n);
    return nNextFromHead(this.tail(), n);
};

proto.tail = function ( n ) {
    if ( n < 0 ) return this.head(-n);
    return nPreviousFromTail(this.head(), n);
};

proto.reverseHead = function ( n ) {
    if ( n < 0 ) return this.reverseTail(-n);
    return nNextFromHead(this.reverseTail(), n);
};

proto.reverseTail = function ( n ) {
    if ( n < 0 ) return this.reverseHead(-n);
    return nPreviousFromTail(this.reverseHead(), n);
};

function nNextFromHead ( it, n ) {
    var q = [];
    n = ToInteger(n);
    if ( n == 0 ) {  // simple optimization
        while ( !it.isHead() ) it = it.previous();
        return it;
    } else {
        while ( n-- > 0 ) {
            if ( it.isHead() ) throw new RangeError();
            q.push(it);
            it = it.previous();
        }
        while ( !it.isHead() ) {
            q.shift();
            q.push(it);
            it = it.previous();
        }
        q.push(it);
        return q[0];
    }
}

function nPreviousFromTail ( it, n ) {
    var q = [];
    n = ToInteger(n);
    if ( n == 0 ) {  // simple optimization
        while ( !it.isTail() ) it = it.next();
        return it;
    } else {
        while ( n-- > 0 ) {
            if ( it.isTail() ) throw new RangeError();
            q.push(it);
            it = it.next();
        }
        while ( !it.isTail() ) {
            q.shift();
            q.push(it);
            it = it.next();
        }
        q.push(it);
        return q[0];
    }
}

proto.iterator = function ( /* delegate */ ) {
    return this.head.apply(this, arguments);
};

proto.add = function ( /* variable args */ ) {
    if ( arguments.length == 0 ) return false;
    for ( var i=0;  i < arguments.length;  i++ ) {
        this.tail().insert(arguments[i]);
    }
    return true;
};

// Returns the value indexed by the argument.
// If there is no corresponding value in this list, returns undefined.
// The argument can be either number or iterator.
proto.get = function ( it ) {
    if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
        try {
            it = this.head(it);
        } catch ( e ) {
            if ( e instanceof RangeError ) {
                return undefined;
            } else {
                throw e;
            }
        }
    }
    if ( it.isTail() ) return undefined;
    else               return it.value();
};

// Assigns the second argument to the container indexed by the first
// argument.
// The argument can be either number or iterator.
proto.set = function ( it, v ) {
    if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
        it = this.head(it);
    }
    return it.assign(v);
};

// Inserts a new container at the position indexed by the first
// argument, and sets the second argument to the container, then,
// returns the value of the container.
// The argument can be either number or iterator.
// The position which this iterator points to after insertion is
// implementation-dependent.
proto.insertAt = function ( it, v ) {
    if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
        it = this.head(it);
    }
    return it.insert(v);
};

// Removes the container indexed by the argument, then, returns the
// value of the container.
// The argument can be either number or iterator.
// The position which this iterator points to after removal is
// implementation-dependent.
proto.removeAt = function ( it ) {
    if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
        it = this.head(it);
    }
    return it.remove();
};

proto.pop = function ( ) {
    return this.reverseHead().remove();
};

proto.push = function ( /* variable args */ ) {
    this.add.apply(this, arguments);
    return this.size();
};

proto.shift = function ( ) {
    return this.head().remove();
};

proto.unshift = function ( /* variable args */ ) {
    for ( var i=arguments.length-1;  i >= 0;  i-- ) {
        this.head().insert(arguments[i]);
    }
    return this.size();
};

proto.join = function ( /* delegate */ ) {
    var arr = this.toArray();
    return arr.join.apply(arr, arguments);
};

proto.toString = function ( /* delegate */ ) {
    var arr = this.toArray();
    return arr.toString.apply(arr, arguments);
};

proto.toLocaleString = function ( /* delegate */ ) {
    var arr = this.toArray();
    return arr.toLocaleString.apply(arr, arguments);
};

proto.reverse = function ( ) {
    var r = this.emptyCopy();
    for ( var it=this.reverseHead();  !it.isTail();  it=it.next() ) {
        r.add(it.value());
    }
    return r;
};

proto.slice = function ( start, end ) {
    if ( !(    start instanceof List.Iterator
            &&   end instanceof List.Iterator
            && start.isBoundTo(this) && end.isBoundTo(this)
            && start.constructor === end.constructor ) )  // one might be reverse-iterator even though the other is iterator.
    {
        try {
            start = this.head(start);
        } catch ( e ) {
            if ( e instanceof RangeError ) {
                start = start < 0 ? this.head() : this.tail();
            } else {
                throw e;
            }
        }
        if ( end === undefined ) {
            end = this.tail();
        } else {
            try {
                end = this.head(end);
            } catch ( e ) {
                if ( e instanceof RangeError ) {
                    end = end < 0 ? this.head() : this.tail();
                } else {
                    throw e;
                }
            }
        }
    }
    var l = this.emptyCopy();
    if ( start.compareTo(end) >= 0 ) return l;
    while ( !start.equals(end) ) {
        l.add(start.value());
        start = start.next();
    }
    return l;
};

proto.concat = function ( /* variable arguments */ ) {
    var list = this.emptyCopy();
    arguments[-1] = this;
    for ( var i=-1;  i < arguments.length;  i++ ) {
        var e = arguments[i];
        if ( e instanceof List ) {
            e.forEach(function(it){
                list.add(it)
            });
        }
        else if ( e instanceof Array ) {
            for ( var j=0;  j < e.length;  j++ ) list.add(e[j])
        }
        else {
            list.add(e);
        }
    }
    return list;
};

proto.foldl = proto.fold;

proto.foldl1 = proto.fold1;

proto.foldr = function ( f, s ) {
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( var it=this.reverseHead();  !it.isTail();  it=it.next() ) {
        try {
            s = g(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return e.result;
            else                                   throw e;
        }
    }
    return s;
};

proto.foldr1 = function ( f ) {
    var it = this.reverseHead();
    if ( it.isTail() ) throw new EmptyEnumerationError();
    var s = it.value();
    it = it.next();
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( ;  !it.isTail();  it=it.next() ) {
        try {
            s = g(it.value());
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return e.result;
            else                                   throw e;
        }
    }
    return s;
};

            return {
                List: List
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Functional.List = List;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.List || (typeof this.Data.Functional.List != 'object' && typeof this.Data.Functional.List != 'function') ) this.Data.Functional.List = new Object();
    if ( this.Data.Functional.List.Iterator === undefined ) this.Data.Functional.List.Iterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.List ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional.List';

function Iterator ( ) {
    // This is a kind of abstract class.
}

var proto = Iterator.prototype = new BidirectionalIterator();
proto.constructor = Iterator;

var obj_name = "[object " + NAMESPACE + ".Iterator]";

proto.toString = function ( ) {
    return obj_name;
};

// Assign the argument to the element which is just after the position
// this iterator points to, then returns the new value of the element,
// which can be defferent from the argument.
// The effect of assignment at the tail of a list should be identical
// to the one of insertion.
// The default implementation merely throws UnimplementedMethodError.
proto.assign = function ( v ) {
    throw new UnimplementedMethodError("assign", this);
};

// Inserts a new container at the position which this iterator points
// to and sets the argument to the container, then, returns the value
// of the container, which can be defferent from the argument.
// The position which the iterator points to after insertion is
// implementation-dependent.
// The default implementation merely throws UnimplementedMethodError.
proto.insert = function ( v ) {
    throw new UnimplementedMethodError("insert", this);
};

// Removes the container just after the position which this iterator
// points, then, returns the value of the container.
// The position which the iterator points to after removal is
// implementation-dependent.
// The default implementation merely throws UnimplementedMethodError.
proto.remove = function ( ) {
    throw new UnimplementedMethodError("remove", this);
};

// Returns true if both this iterator and the argument points to the same position,
// false otherwise.
// The default implementation is based on `compareTo' method.
proto.equals = function ( that ) {
    return this.compareTo(that) === 0;
};

// Returns the distance of this iterator and the argument,
// or undefined if the iterators seem to point to defferent list.
// A negative return value means the arguments succeeds this iterator
// and its magnitude represents the distance of them. Thus, this can be
// used as comparison-function.
// The default implementation is based on `next', `equals' and `isTail' method.
proto.distance  =
proto.compareTo = function ( that ) {
    if ( !(that instanceof Iterator) ) return undefined;
    for ( var i=0, l=this, r=that;  ;  i--, l=l.next() ) {
        if ( l.equals(r) ) return i;
        if ( l.isTail() ) break;
    }
    for ( var i=1, l=that.next(), r=this;  ;  i++, l=l.next() ) {
        if ( l.equals(r) ) return i;
        if ( l.isTail() ) break;
    }
    return undefined;
};

            return {
                Iterator: Iterator
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Functional.List.Iterator = Iterator;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.List || (typeof this.Data.Functional.List != 'object' && typeof this.Data.Functional.List != 'function') ) this.Data.Functional.List = new Object();
    if ( this.Data.Functional.List.ReverseIterator === undefined ) this.Data.Functional.List.ReverseIterator = undefined;
with ( function(){
with ( Data.Functional.List ) {

        return function () {
            var VERSION = '0.4.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Functional.List';

// This module provides convinient wrapper to construct
// reverse iterator from normal list iterator.

function ReverseIterator ( it ) {
    this._it = it;
}

var proto = ReverseIterator.prototype = new Iterator();
proto.constructor = ReverseIterator;

proto.isBoundTo = function ( that ) {
    return this._it.isBoundTo(that);
};

proto.isTail = function ( ) {
    return this._it.isHead();
};

proto.isHead = function ( ) {
    return this._it.isTail();
};

proto.next = function ( ) {
    return new ReverseIterator(this._it.previous());
};

proto.previous = function ( ) {
    return new ReverseIterator(this._it.next());
};

proto.value = function ( ) {
    return this._it.previous().value();
};

proto.assign = function ( v ) {
    return this._it.previous().assign(v);
};

proto.insert = function ( v ) {
    return this._it.insert(v);
};

proto.remove = function ( ) {
    return this._it.previous().remove();
};

proto.equals = function ( that ) {
    if ( !(that instanceof ReverseIterator) ) return false;
    return this._it.equal(taht._it);
};

proto.compareTo = function ( that ) {
    if ( !(that instanceof ReverseIterator) ) return undefined;
    var c = this._it.compareTo(that._it);
    if ( isNaN(d) ) return c;
    return -c;
};

proto.distance = function ( that ) {
    if ( !(that instanceof ReverseIterator) ) return undefined;
    var d = this._it.distance(that._it);
    if ( isNaN(d) ) return d;
    return -d;
};

            return {
                ReverseIterator: ReverseIterator
            };
        }();
    }
}.call(null) ) {
    this.Data.Functional.List.ReverseIterator = ReverseIterator;
}
}).call(null);
(function(){
with ( function(){

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// This is just a alias.
// See "Data.Functional.List.list" for the entity of "Data.Functional.List".

            return {

            };
        }();
    }.call(null) ) {
}
}).call(null);
(function(){
    if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Data.Cons.list === undefined ) this.Data.Cons.list = undefined;
    if ( this.Data.Cons.InsertAtHeadError === undefined ) this.Data.Cons.InsertAtHeadError = undefined;
    if ( this.Data.Cons.RemoveHeadError === undefined ) this.Data.Cons.RemoveHeadError = undefined;
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {
with ( Data.Cons ) {

        return function () {
            var VERSION = '0.2.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Cons code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Cons';

var proto = new List();
proto.toString       = Cell.prototype.toString;
proto.toLocaleString = Cell.prototype.toLocaleString;
proto.isNil          = Cell.prototype.isNil;
Cell.prototype = proto;
proto.constructor = Cell;

proto = new Cell();
proto.toString       = Nil.prototype.toString;
proto.toLocaleString = Nil.prototype.toLocaleString;
proto.isNil          = Nil.prototype.isNil;
Nil.prototype = proto;
proto.constructor = Nil;

function list ( /* variable args */ ) {
    var head, cell;
    head = cell = new Cell(null, new Nil());
    for ( var i=0;  i < arguments.length;  i++ ) {
        cell = cell.cdr = new Cell(arguments[i], cell.cdr);
    }
    return head.cdr;
}

proto = Cell.prototype;

proto.iterator =
proto.head     = function ( n ) {
    n = ToInteger(n);
    if ( n < 0 ) return this.tail(-n);
    try {
        for ( var it=new Iterator(this, this, null);  n > 0;  it=it.next(), n-- );
        return it;
    } catch ( e ) {
        if ( e instanceof NoSuchElementError ) {
            throw new RangeError();
        } else {
            throw e;
        }
    }
};

proto.tail = function ( n ) {
    n = ToInteger(n);
    if ( n < 0 ) return this.head(-n);
    for ( var it=new Iterator(this, this, null);  !it.isTail();  it=it.next() );
    try {
        for ( ;  n > 0;  it=it.previous(), n-- );
        return it;
    } catch ( e ) {
        if ( e instanceof NoSuchElementError ) {
            throw new RangeError();
        } else {
            throw e;
        }
    }
};

proto.reverseHead = function ( n ) {
    return new ReverseIterator(this.tail(n));
};

proto.reverseTail = function ( n ) {
    return new ReverseIterator(this.head(n));
};

proto.get = function ( n ) {
    if ( n instanceof Iterator || n instanceof ReverseIterator ) {
        if ( !n.isBoundTo(this) ) throw new IllegalStateError();
        return n.value();
    }
    n = ToInteger(n);
    if ( n < 0 ) return this.reverse().get(-n-1);
    var c = this;
    while ( n !== 0 ) {
        c = c.cdr;
        if ( c.isNil() ) return undefined;
        n--;
    }
    return c.car;
};

proto.set = function ( n, v ) {
    if ( n instanceof Iterator || n instanceof ReverseIterator ) {
        if ( !n.isBoundTo(this) ) throw new IllegalStateError();
        return n.assign(v);
    }
    return this.head(n).assign(v);
};

proto.add = function ( /* variable args */ ) {
    if ( arguments.length == 0 ) return false;
    if ( this.isNil() ) throw new InsertAtHeadError();
    for ( var c=this;  !c.cdr.isNil();  c=c.cdr );
    for ( var i=0;  i < arguments.length;  i++ ) {
        c = c.cdr = new Cell(arguments[i], new Nil());
    }
    return true;
};

proto.shift = function ( ) {
    throw new RemoveHeadError();
};

proto.unshift = function ( ) {
    throw new InsertAtHeadError();
};

proto.pop = function ( ) {
    if ( this.isNil() ) return undefined;
    if ( this.cdr.isNil() ) throw new RemoveHeadError();
    for ( var c=this.cdr;  !c.cdr.cdr.isNil();  c=c.cdr );
    var r = c.cdr.car;
    c.cdr = c.cdr.cdr;
    return r;
};

proto.push = function ( /* variable args */ ) {
    if ( arguments.length == 0 ) return this.size();
    if ( this.isEmpty() ) throw new InsertAtHeadError();
    for ( var l=1, c=this;  !c.cdr.isNil();  l++, c=c.cdr );
    for ( var i=0;  i < arguments.length;  i++, l++ ) {
        c = c.cdr = new Cell(arguments[i], c.cdr);
    }
    return l;
};

proto.isEmpty = function ( ) {
    return this.isNil();
};

proto.empty = function ( ) {
    if ( this.isEmpty() ) return;
    throw new RemoveHeadError();
};

proto.size = function ( ) {
    for ( var i=0, c=this;  !c.isNil();  i++, c=c.cdr );
    return i;
};

proto.copy = function ( ) {
    if ( this.isNil() ) return new Nil();
    var head, cell;
    head = cell = new Cell(this.car, new Nil());
    for ( var c=this.cdr;  !c.isNil();  c=c.cdr ) {
        cell = cell.cdr = new Cell(c.car, cell.cdr);
    }
    return head;
};

proto.toArray = function ( ) {
    var a = [];
    for ( var c=this;  !c.isNil();  c=c.cdr ) a.push(c.car);
    return a;
};

proto.reverse = function ( ) {
    var r = new Nil();
    for ( var c=this;  !c.isNil();  c=c.cdr ) r = new Cell(c.car, r);
    return r;
};

proto.concat = function ( /* variable args */ ) {
    var head, cell;
    head = cell = new Cell(null, new Nil());
    arguments[-1] = this;
    for ( var i=-1;  i < arguments.length;  i++ ) {
        var c = arguments[i];
        if ( c instanceof List ) {
            c.forEach(function( it ){
                cell = cell.cdr = new Cell(it, cell.cdr);
            });
        } else if ( c instanceof Array ) {
            for ( var j=0;  j < c.length;  j++ ) {
                cell = cell.cdr = new Cell(c[j], cell.cdr);
            }
        } else {
            cell = cell.cdr = new Cell(c, cell.cdr);
        }
    }
    return head.cdr;
};

proto.slice = function ( start, end ) {
    if ( !( (   start instanceof Iterator        && end instanceof Iterator
             || start instanceof ReverseIterator && end instanceof ReverseIterator )
           && start.isBoundTo(this) && end.isBoundTo(this) ) )
    {   try {
            start = this.head(start);
        } catch ( e ) {
            if ( e instanceof RangeError ) {
                start = start < 0 ? this.head() : this.tail();
            } else {
                throw e;
            }
        }
        if ( end === undefined ) {
            end = this.tail();
        } else {
            try {
                end = this.head(end);
            } catch ( e ) {
                if ( e instanceof RangeError ) {
                    end = end < 0 ? this.head() : this.tail();
                } else {
                    throw e;
                }
            }
        }
    }
    if ( start.compareTo(end) >= 0 ) return new Nil();
    var head, cell;
    head = cell = new Cell(null, new Nil());
    while ( !start.equals(end) ) {
        cell = cell.cdr = new Cell(start.value(), cell.cdr);
        start = start.next();
    }
    return head.cdr;
}

proto.forEach = function ( f ) {
    f = wrap_for_forEach(this, f);
    for ( var c=this;  !c.isNil();  c=c.cdr ) {
        try {
            f(c.car);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return;
            } else {
                throw e;
            }
        }
    }
};

proto.fold  =
proto.foldl = function ( f, s ) {
    f = wrap_for_fold(this, f, s);
    for ( var c=this;  !c.isNil();  c=c.cdr ) {
        try {
            s = f(c.car);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
    if ( this.isEmpty() ) throw new EmptyEnumerationError();
    var s = this.car;
    f = wrap_for_fold(this, f, s);
    for ( var c=this.cdr;  !c.isNil();  c=c.cdr ) {
        try {
            s = f(c.car);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.foldr = function ( f, s ) {
    return this.reverse().foldl(function(x,y){return f.call(this,y,x);}, s);
};

proto.foldr1 = function ( f ) {
    return this.reverse().foldl1(function(x,y){return f.call(this,y,x);});
};

proto.map = function ( f ) {
    if ( this.isNil() ) return new Nil();
    var head, cell;
    head = cell = new Cell(null, new Nil());
    f = wrap_for_map(this, f, function(){
        for ( var i=0;  i < arguments.length;  i++ ) {
            cell = cell.cdr = new Cell(arguments[i], cell.cdr);
        }
    });
    for ( var c=this;  !c.isNil();  c=c.cdr ) {
        try {
            f(c.car);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return head.cdr;
            } else {
                throw e;
            }
        }
    }
    return head.cdr;
}

function Iterator ( head, cell, prev ) {
    this._head = head;
    this._cell = cell;
    this._prev = prev;
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

proto.isBoundTo = function ( that ) {
    return this._head === that;
};

proto.isHead = function ( ) {
    return this._head === this._cell;
};

proto.isTail = function ( ) {
    return this._cell.isNil();
};

proto.value = function ( ) {
    return this._cell.car;
};

proto.assign = function ( v ) {
    if ( this.isTail() ) this.insert(v);
    else                 this._cell.car = v;
    return v;
};

proto.insert = function ( v ) {
    if ( this.isHead() ) throw new InsertAtHeadError();
    this._cell = this._prev._cell.cdr = new Cell(v, this._cell.cdr);
    return v;
};

proto.remove = function ( ) {
    if ( this.isHead() ) throw new RemoveHeadError();
    if ( this.isTail() ) throw new IllegalStateError("can't remove at tail");
    var r = this._cell.car;
    this._cell = this._prev._cell.cdr = this._cell.cdr;
    return r;
};

proto.next = function ( ) {
    if ( this.isTail() ) throw new NoSuchElementError("no next element");
    return new Iterator(this._head, this._cell.cdr, this);
};

proto.previous = function ( ) {
    if ( this.isHead() ) throw new NoSuchElementError("no previous element");
    return this._prev;
};

proto.equals = function ( that ) {
    return that instanceof Iterator
        && that.isBoundTo(this._head)
        && this._cell === that._cell;
};

proto.compareTo =
proto.distance  = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._head)) ) return undefined;
    for ( var i=0, l=this._cell, r=that._cell;  !l.isNil();  i++, l=l.cdr ) {
        if ( l === r ) return -i;
    }
    for ( var i=1, l=that._cell.cdr, r=this._cell;  !l.isNil();  i++, l=l.cdr ) {
        if ( l === r ) return i;
    }
    return void 0;
};

function ReverseIterator ( ) {
    return List.ReverseIterator.apply(this, arguments);
}

var proto = ReverseIterator.prototype = new List.ReverseIterator();
proto.constructor = ReverseIterator;

var InsertAtHeadError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".InsertAtHeadError",
        message: "can't insert at head of cons-list"
    }
);

var RemoveHeadError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".RemoveHeadError",
        message: "can't remove head of cons-list"
    }
);

            return {
                InsertAtHeadError: InsertAtHeadError, RemoveHeadError: RemoveHeadError, list: list
            };
        }();
    }
}
}
}
}
}
}.call(null) ) {
    this.Data.Cons.InsertAtHeadError = InsertAtHeadError;
    this.Data.Cons.RemoveHeadError = RemoveHeadError;
    this.Data.Cons.list = list;
}
}).call(null);
(function(){
    if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

        return function () {
            var VERSION = '0.5.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Functional code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

var proto = Array.prototype;

for ( var i in List.prototype ) {
    if ( typeof proto[i] != "function" ) proto[i] = List.prototype[i];
}

proto.head = function ( n ) {
    if ( n < 0 ) return this.tail(-n);
    n = ToInteger(n);
    if ( n > this.length ) throw new RangeError();
    return new Iterator(this, n);
};

proto.tail = function ( n ) {
    if ( n < 0 ) return this.head(-n);
    n = ToInteger(n);
    if ( n > this.length ) throw new RangeError();
    return new Iterator(this, this.length-n);
};

proto.iterator = proto.head;

proto.reverseHead = function ( n ) {
    if ( n < 0 ) return this.reverseTail(-n);
    n = ToInteger(n);
    if ( n > this.length ) throw new RangeError();
    return new ReverseIterator(this, n);
};

proto.reverseTail = function ( n ) {
    if ( n < 0 ) return this.reverseHead(-n);
    n = ToInteger(n);
    if ( n > this.length ) throw new RangeError();
    return new ReverseIterator(this, this.length-n);
};

proto.add = function ( /* variable args */ ) {
    this.push.apply(this, arguments);
    return true;
};

proto.get = function ( it ) {
    if ( it instanceof Iterator || it instanceof ReverseIterator ) {
        if ( it.isBoundTo(this) ) return it.value();
        throw new IllegalStateError();
    }
    it = ToInteger(n);
    if ( it < 0 ) it += this.length;
    return this[it];
};

proto.set = function ( it, v ) {
    if ( it instanceof Iterator || it instanceof ReverseIterator ) {
        if ( it.isBoundTo(this) ) return it.assign(v);
        throw new IllegalStateError();
    }
    var n = ToInteger(it);
    if ( n < 0            ) n += this.length;
    if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
    if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
    return this[n] = v;
};

proto.insertAt = function ( it, v ) {
    if ( it instanceof Iterator || it instanceof ReverseIterator ) {
        if ( it.isBoundTo(this) ) return it.insert(v);
        throw new IllegalStateError();
    }
    var n = ToInteger(it);
    if ( n < 0            ) n += this.length;
    if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
    if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
    this.splice(n, 0, v);
    return v;
};

proto.removeAt = function ( it ) {
    if ( it instanceof Iterator || it instanceof ReverseIterator ) {
        if ( it.isBoundTo(this) ) return it.remove();
        throw new IllegalStateError();
    }
    var n = ToInteger(it);
    if ( n < 0            ) n += this.length;
    if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
    if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
    return this.splice(n, 1)[0];
};

proto.isEmpty = function ( ) {
    return this.length == 0;
};

proto.empty = function ( ) {
    this.length = 0;
};

proto.size = function ( ) {
    return this.length;
};

proto.copy    =
proto.toArray = function ( ) {
    var a = [];
    for ( var i=0;  i < this.length;  i++ ) a[i] = this[i];
    return a;
};

proto.forEach = function ( f ) {
    f = wrap_for_forEach(this, f);
    for ( var i=0;  i < this.length;  i++ ) {
        try {
            f(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return;
            } else {
                throw e;
            }
        }
    }
};

proto.fold  =
proto.foldl = function ( f, s ) {
    f = wrap_for_fold(this, f, s);
    for ( var i=0;  i < this.length;  i++ ) {
        try {
            s = f(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
    if ( this.length == 0 ) throw new EmptyEnumerationError();
    var s = this[0];
    f = wrap_for_fold(this, f, s);
    for ( var i=1;  i < this.length;  i++ ) {
        try {
            s = f(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.foldr = function ( f, s ) {
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( var i=this.length-1;  i >= 0;  i-- ) {
        try {
            s = f(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.foldr1 = function ( f ) {
    if ( this.length == 0 ) throw new EmptyEnumerationError();
    var s = this[this.length-1];
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( var i=this.length-2;  i >= 0;  i-- ) {
        try {
            s = g(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.map = function ( f ) {
    var a = [];
    f = wrap_for_map(this, f, function(){
        a.push.apply(a, arguments);
    });
    for ( var i=0;  i < this.length;  i++ ) {
        try {
            f(this[i]);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return a;
            else                                   throw e;
        }
    }
    return a;
};

// Re-define concat and slice
var original_concat = proto.concat;
proto.concat = function ( /* variable argumentes */ ) {
    for ( var i=0;  i < arguments.length;  i++ ) {
        var v = arguments[i];
        if ( v instanceof List ) arguments[i] = v.toArray();
    }
    return original_concat.apply(this, arguments);
};

var original_slice = proto.slice;
proto.slice = function ( start, end ) {
    if (   (   start instanceof Iterator        && end instanceof Iterator
            || start instanceof ReverseIterator && end instanceof ReverseIterator )
        && start.isBoundTo(this) && end.isBoundTo(this)  )
    {
        if ( start.compareTo(end) >= 0 ) return [];
        var s = [];
        do {
            s.push(start.value());
            start = start.next();
        } while ( !start.equals(end) );
        return s;
    } else {
        return original_slice.apply(this, arguments);
    }
};

function Iterator ( a, n ) {
    this._arr = a;
    this._pos = n;
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

proto.isBoundTo = function ( that ) {
    return this._arr === that;
};

proto.isHead = function ( ) {
    return ToInteger(this._pos) <= 0
        || this._arr.length == 0;
};

proto.isTail = function ( ) {
    return ToInteger(this._pos) >= this._arr.length
        || this._arr.length == 0;
};

proto.value = function ( ) {
    if ( this.isTail() ) return undefined;
    if ( this.isHead() ) return this._arr[0];
    else                 return this._arr[ToInteger(this._pos)];
};

proto.assign = function ( v ) {
    if ( this.isTail() ) return this.insert();
    if ( this.isHead() ) return this._arr[0] = v;
    else                 return this._arr[ToInteger(this._pos)] = v;
};

proto.insert = function ( v ) {
    var i = ToInteger(this._pos);
    if ( i <= 0 ) i = 0;
    else          i = min(i, this._arr.length);
    return this._arr.insertAt(i, v);
};

proto.remove = function ( ) {
    if      ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
    else if ( this.isHead() ) return this._arr.aplice(0, 1)[0];
    else                      return this._arr.splice(this._pos, 1)[0];
};

proto.next = function ( ) {
    if ( this.isTail() ) throw new NoSuchElement("no next element");
    if ( this.isHead() ) return new this.constructor(this._arr, 1);
    else                 return new this.constructor(this._arr, this._pos+1);
};

proto.previous = function ( ) {
    if ( this.isHead() ) throw new NoSuchElement("no previous element");
    if ( this.isTail() ) return new this.constructor(this._arr, this._arr.length-1);
    else                 return new this.constructor(this._arr, this._pos-1);
};

proto.compareTo =
proto.distance  = function ( that ) {
    if ( !(that instanceof this.constructor) ) return undefined;
    if ( this._arr !== that._arr             ) return undefined;
    var s = this._arr.length;
    var l = ToInteger(this._pos);
    var r = ToInteger(that._pos);
    if ( l <= 0  &&  r <= 0
      || l >= s  &&  r >= s ) return 0;
    return l - r;
};

function ReverseIterator ( a, n ) {
    Iterator.apply(this, arguments);
}

var proto = ReverseIterator.prototype = new List.Iterator();

for ( var i in Iterator.prototype ) {
    if ( Iterator.prototype.hasOwnProperty(i)
      && typeof Iterator.prototype[i] == "function" )
    {
        proto[i] = Iterator.prototype[i];
    }
}

proto.constructor = ReverseIterator;

proto.value = function ( ) {
    if ( this.isTail() ) return undefined;
    if ( this.isHead() ) return this._arr[this._arr.length-1];
    else                 return this._arr[this._arr.length-1-ToInteger(this._pos)];
};

proto.assign = function ( v ) {
    if ( this.isTail() ) this.insert(v);
    if ( this.isHead() ) return this._arr[this._arr.length-1] = v;
    else                 return this._arr[this._arr.length-1-ToInteger(this._pos)] = v;
};

proto.insert = function ( v ) {
    var i = ToInteger(this._pos);
    if ( i <= 0 ) i = 0;
    else          i = min(i, this._arr.length);
    return this._arr.insertAt(this._arr.length-i, v);
};

proto.remove = function ( ) {
    if ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
    if ( this.isHead() ) return this._arr.splice(this._arr.length-1, 1)[0];
    else                 return this._arr.splice(this._arr.length-1-ToInteger(this._pos), 1)[0];
};

            return {

            };
        }();
    }
}
}
}
}.call(null) ) {
}
}).call(null);
(function(){
    if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Data.LinkedList === undefined ) this.Data.LinkedList = undefined;
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {
with ( Data ) {

        return function () {
            var VERSION = '0.3.1';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.LinkedList module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2005-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data';

function LinkedList ( /* variable arguments */ ) {
    this._value   = undefined;
    this._prev    = this;
    this._next    = this;
    this._removed = false;
    this.add.apply(this, arguments);
}

LinkedList.fromCollection = function ( /* variable args */ ) {
    var l = new LinkedList();
    l.addAll.apply(l, arguments);
    return l;
};

function makeContainer ( v ) {
    return { _value: v, _removed: false };
}

var proto = LinkedList.prototype = new List();
proto.constructor = LinkedList;

function nForward ( top, c, n ) {
    if ( n == 0 ) return c;
    c = c._next;
    while ( --n > 0 ) {
        if ( c === top ) throw new RangeError();
        c = c._next;
    }
    return c;
}

function nBackward ( top, c, n ) {
    if ( n == 0 ) return c;
    c = c._prev;
    while ( --n > 0 ) {
        if ( c === top ) throw new RangeError();
        c = c._prev;
    }
    return c;
}

proto.head = function ( n ) {
    if ( n < 0 ) return this.tail(-n);
    return new Iterator( this, nForward(this, this._next, ToInteger(n)) );
};

proto.tail = function ( n ) {
    if ( n < 0 ) return this.head(-n);
    return new Iterator( this, nBackward(this, this, ToInteger(n)) );
};

proto.reverseHead = function ( n ) {
    if ( n < 0 ) return this.reverseTail(-n);
    return new ReverseIterator( this, nBackward(this, this._prev, ToInteger(n)) );
};

proto.reverseTail = function ( n ) {
    if ( n < 0 ) return this.reverseHead(-n);
    return new ReverseIterator( this, nBackward(this, this, ToInteger(n)) );
};

proto.iterator = proto.head;

proto.add = function ( /* variable args */ ) {
    if ( !arguments.length ) return false;
    var it = new Iterator(this, this);
    for ( var i=0;  i < arguments.length;  i++ ) it.insert(arguments[i]);
    return true;
};

proto.pop = function ( ) {
    return (new Iterator(this, this._prev)).remove();
};

proto.shift = function ( ) {
    return (new Iterator(this, this._next)).remove();
};

proto.unshift = function ( /* variable arguments */ ) {
    var it = new Iterator(this, this._next);
    for ( var i=0;  i < arguments.length;  i++ ) it.insert(arguments[i]);
    return this.size();
};

proto.isEmpty = function ( ) {
    return this._next === this;
};

proto.empty = function ( ) {
    this._prev = this._next = this;
};

proto.size = function ( ) {
    for ( var i=0, c=this._next;  c !== this;  ++i, c=c._next );
    return i;
};

proto.copy = function ( ) {
    var l = this.emptyCopy();
    for ( var c=this._next;  c !== this;  c=c._next ) l.add(c._value);
    return l;
};

proto.toArray = function ( ) {
    var a = [];
    for ( var c=this._next;  c !== this;  c=c._next ) a.push(c._value);
    return a;
};

proto.forEach = function ( f ) {
    f = wrap_for_forEach(this, f);
    for ( var c=this._next;  c !== this;  c=c._next ) {
        try {
            f(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return;
            } else {
                throw e;
            }
        }
    }
}

proto.fold  =
proto.foldl = function ( f, s ) {
    f = wrap_for_fold(this, f, s);
    for ( var c=this._next;  c !== this;  c=c._next ) {
        try {
            s = f(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
    if ( this.isEmpty() ) throw new EmptyEnumerationError();
    var s = this._next._value;
    f = wrap_for_fold(this, f, s);
    for ( var c=this._next._next;  c !== this;  c=c._next ) {
        try {
            s = f(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.foldr = function ( f, s ) {
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( var c=this._prev;  c !== this;  c=c._prev ) {
        try {
            s = f(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.foldr1 = function ( f ) {
    if ( this.isEmpty() ) throw new EmptyEnumerationError();
    var s = this._prev._value;
    var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
    for ( var c=this._prev._prev;  c !== this;  c=c._prev ) {
        try {
            s = g(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) {
                return e.result;
            } else {
                throw e;
            }
        }
    }
    return s;
};

proto.map = function ( f ) {
    var l = new LinkedList();
    f = wrap_for_map(this, f, function(){
        l.add.apply(l, arguments);
    });
    for ( var c=this._next;  c !== this;  c=c._next ) {
        try {
            f(c._value);
        } catch ( e ) {
            if ( e instanceof EndOfLoopException ) return l;
            else                                   throw e;
        }
    }
    return l;
};

// comparison function about containers
function comp ( top, l, r ) {
    if ( l === r ) return 0;
    do {
        l = l._next;
        if ( l === r ) return -1;
    } while ( l !== top );
    return 1;
}

// distance function about containers
function dist ( top, l, r ) {
    for ( var i=0, it=l;  it !== top;  i--, it=it._next ) {
        if ( it === r ) return i;
    }
    for ( var i=1, it=r._next;  it !== top;  i++, it=it._next ) {
        if ( it === l ) return i;
    }
    return undefined;
}

function Iterator ( l, c ) {
    this._top = l;  // LinkedList object which this iterator belongs to.
    this._pos = c;  // Current position; abstractly iterator points to just before this container
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

function validate ( it ) {
    while ( it._pos._removed ) {
        it._pos = it._pos._next;
    }
}

proto.isBoundTo = function ( that ) {
    return this._top === that;
};

proto.equals = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return false;
    validate(this);
    validate(that);
    return  this._pos === that._pos;
};

proto.compareTo = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
    validate(this);
    validate(that);
    return comp(this._top, this._pos, that._pos);
};

proto.distance = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
    validate(this);
    validate(that);
    return dist(this._top, this._pos, that._pos);
};

proto.isHead = function ( ) {
    validate(this);
    return this._pos === this._top._next;
};

proto.isTail = function ( ) {
    validate(this);
    return this._pos === this._top;
};

proto.next = function ( ) {
    if ( this.isTail() ) throw new NoSuchElementError("no next element");
    return new Iterator(this._top, this._pos._next);
};

proto.previous = function ( ) {
    if ( this.isHead() ) throw new NoSuchElementError("no previous element");
    return new Iterator(this._top, this._pos._prev);
};

proto.value = function ( ) {
    validate(this);
    return this._pos._value;
};

proto.assign = function ( v ) {
    if ( this.isTail() ) return this.insert(v);
    else                 return this._pos._value = v;
};

proto.insert = function ( v ) {
    validate(this);
    var c = makeContainer(v);
    c._prev = this._pos._prev;
    c._next = this._pos;
    this._pos._prev = this._pos._prev._next = c;
    return v;
};

proto.remove = function ( ) {
    if ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
    this._pos._prev._next = this._pos._next;
    this._pos._next._prev = this._pos._prev;
    this._pos._removed = true;
    return this._pos._value;
};

function ReverseIterator ( l, c ) {
    this._top = l;  // LinkedList object which this iterator belongs to.
    this._pos = c;  // Current position; abstractly iterator points to just before this container
}

var proto = ReverseIterator.prototype = new List.Iterator();
for ( var i in Iterator.prototype ) proto[i] = Iterator.prototype[i];
proto.constructor = ReverseIterator;

function rvalidate ( it ) {
    while ( it._pos._removed ) {
        it._pos = it._pos._prev;
    }
}

proto.isBoundTo = Iterator.prototype.isBoundTo;

proto.equals = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return false;
    rvalidate(this);
    rvalidate(that);
    return  this._pos === that._pos;
};

proto.compareTo = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
    rvalidate(this);
    rvalidate(that);
    return -comp(this._top, this._pos, that._pos);
};

proto.distance = function ( that ) {
    if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
    rvalidate(this);
    rvalidate(that);
    var d = dist(this._top, this._pos, that._pos);
    return isNaN(d) ? d : -d;
};

proto.isHead = function ( ) {
    rvalidate(this);
    return this._pos === this._top._prev;
};

proto.isTail = function ( ) {
    rvalidate(this);
    return this._pos === this._top;
};

proto.next = function ( ) {
    if ( this.isTail() ) throw new NoSuchElementError("no next element");
    return new ReverseIterator(this._top, this._pos._prev);
};

proto.previous = function ( ) {
    if ( this.isHead() ) throw new NoSuchElementError("no previous element");
    return new ReverseIterator(this._top, this._pos._next);
};

proto.value = function ( ) {
    rvalidate(this);
    return this._pos._value;
};

proto.assign = Iterator.prototype.assign;

proto.insert = function ( v ) {
    rvalidate(this);
    var c = makeContainer(v);
    c._next = this._pos._next;
    c._prev = this._pos;
    this._pos._next = this._pos._next._prev = c;
    return v;
};

proto.remove = Iterator.prototype.remove;

            return {
                LinkedList: LinkedList
            };
        }();
    }
}
}
}
}
}
}.call(null) ) {
    this.Data.LinkedList = LinkedList;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( this.Concurrent.Thread === undefined ) this.Concurrent.Thread = undefined;
with ( function(){
with ( Data.Error ) {
with ( Concurrent ) {

        return function () {
            var VERSION = '0.1.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent';

var current_thread = null;  // Retains the current thread.

function NoContinuationException ( r ) {
    this.ret_val = r;
}

function initial_continuation_procedure ( ret_val ) {
    throw new NoContinuationException(ret_val);
}

function NoExceptionHandlerException ( e ) {
    this.thrown = e;
}

function initial_exception_handler ( e ) {
    throw new NoExceptionHandlerException(e);
}

var initial_continuation = {
    this_val : null,
    procedure: initial_continuation_procedure,
    exception: {
        this_val : null,
        procedure: initial_exception_handler
    }
};
// Cyclic reference ensures that at least one exceptinal continuation always exists.
initial_continuation.exception.exception = initial_continuation.exception;

function Thread ( ) {
    throw new Error("Thread cannot be instantiated directly.");
}

function THREAD ( t ) {
    this._triplet      = t;  // {continuation:{...}, timeout:int|undefined, ret_val:any}
    this._is_ended     = 0;  // 0:running, -1:throw, 1:return
    this._join_thread  = null;
    this._joined_list  = new Data.LinkedList();
    this._timerID      = undefined;
    standBy.call(this, 0);
}

var proto = THREAD.prototype = Thread.prototype;

+function(){
    var name = "[object " + NAMESPACE + ".Thread]"
    proto.toString = function ( ) {
        return name;
    };
}();

// Cancel timeout event.
function cancel ( ) {
    if ( this._timerID ) {
        clearTimeout(this._timerID);
        this._timerID = undefined;
    }
}

// Reserve execution of the next step after t msec.
function standBy ( t ) {
    cancel.call(this);
    var self = this;
    this._timerID = setTimeout(
        function(){ doNext.call(self); },
        Number(t) || 2  // some version of IE occationally fails to
                        // context-switch with timeout interval less than 2.
    );
}

// Cut "join" link.
function unjoin ( ) {
    if ( this._join_thread ) {
        var self = this;
        var it = this._join_thread._joined_list.head().find(function( it ){
            return it === self;
        });
        it.remove();
        this._join_thread = null;
    }
}

Thread.TIME_SLICE = 20;

function doNext ( ) {
    cancel.call(this);
    var triplet = this._triplet;
    this._triplet = null;
    try {
        current_thread = this;
        var limit = (new Date).valueOf() + Thread.TIME_SLICE;
        do {
            try {
                triplet = triplet.continuation.procedure.call(
                              triplet.continuation.this_val, triplet.ret_val
                         );
            } catch ( e ) {
                if ( e instanceof NoContinuationException ) {
                    this._is_ended = 1;
                    this._result   = e.ret_val;
                    while ( !this._joined_list.isEmpty() ) {
                        var it = this._joined_list.head().value();
                        unjoin.call(it);
                        it._triplet.ret_val = e.ret_val;
                        standBy.call(it);
                    }
                    this._joined_list = null;
                    return;
                } else if ( e instanceof NoExceptionHandlerException ) {
                    e = e.thrown;
                    var joined_list   = this._joined_list;
                    this._joined_list = null;
                    this._is_ended    = -1;
                    this._result      = e;
                    if ( !joined_list.isEmpty() ) {
                        while ( !joined_list.isEmpty() ) {
                            joined_list.head().value().notify(e);  // "notify" implies "unjoin".
                        }
                    } else if ( !(e instanceof KillException) ) {
                        throw e;
                    }
                    return;
                } else {
                    triplet.continuation = triplet.continuation.exception;
                    triplet.ret_val      = e;
                }
            }
        } while ( triplet.timeout === undefined && (new Date).valueOf() < limit );
    } finally {
        current_thread = null;
    }
    this._triplet = triplet;
    if ( triplet.timeout < 0 ) { /* Do nothing. */                   }
    else                       { standBy.call(this, triplet.timeout); }
}

proto.notify = function ( e ) {
    if ( current_thread === this ) throw e;
    if ( this._is_ended ) throw new NotAliveError();
    cancel.call(this);
    unjoin.call(this);
    this._triplet.continuation = this._triplet.continuation.exception;
    this._triplet.ret_val = e;
    standBy.call(this);
    return e;
};

proto.kill = function ( s ) {
    return this.notify( arguments.length ? new KillException(s) : new KillException() );
};

proto.join = function ( ) {
    throw new Error("can't `join' in non-compiled functions");
};

proto.join.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    //!TODO: check cyclic-join
    if ( this_val._is_ended > 0 ) {  // this thread has already ended normally
        return { continuation:cont, ret_val:this_val._result, timeout:undefined };
    } else if ( this_val._is_ended < 0 ) {  // this thread has already ended by exception
        throw this_val._result;
    } else {
        this_val._joined_list.add(current_thread);
        current_thread._join_thread = this_val;
        return { continuation:cont, timeout:-1 };
    }
};

Thread.create = function ( f /* , ... */ ) {
    if ( typeof f != "function" ) throw new TypeError("can't create new thread from non-function value");
    if ( typeof f.$Concurrent_Thread_compiled !== "function" ) f = this.compile(f);
    return f.async(null, Array.prototype.slice.call(arguments, 1, arguments.length));
};

Thread.self = function ( ) {
    return current_thread;
};

Thread.sleep = function ( ) {
    throw new Error("can't `sleep' in non-compiled functions");
};

Thread.sleep.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    return { continuation: cont,
             ret_val     : undefined,
             timeout     : args[0] > 0 ? args[0] : 0 };
};

Thread.stop = function ( ) {
    throw new Error("can't `stop' in non-compiled functions");
};

Thread.stop.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    return { continuation: cont,
             ret_val     : undefined,
             timeout     : -1        };
};

Thread.yield = function ( ) {
    throw new Error("can't `yield' in non-compiled functions");
};

Thread.yield.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    return { continuation: cont,
             ret_val     : undefined,
             timeout     : 0         };
};

var KillException = Thread.KillException = Exception.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".Thread.KillException",
        message: "thread killed"
    }
);

var NotAliveError = Thread.NotAliveError = Error.extend(
    function ( $super, message ) { $super(message); },
    {
        name   : NAMESPACE + ".Thread.NotAliveError",
        message: "thread not alive"
    }
);

// Extends Function object.
var proto = Function.prototype;

proto.apply.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    if ( typeof this_val.$Concurrent_Thread_compiled == "function" ) {
        return this_val.$Concurrent_Thread_compiled(args[0], args[1], cont);
    } else {
        return { continuation: cont,
                 ret_val     : this_val.apply(args[0], args[1]) };
    }
};

proto.call.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
    if ( typeof this_val.$Concurrent_Thread_compiled == "function" ) {
        return this_val.$Concurrent_Thread_compiled(args[0], Array.prototype.slice.call(args, 1, args.length), cont);
    } else {
        return { continuation: cont,
                 ret_val     : this_val.apply(args[0], Array.prototype.slice.call(args, 1, args.length)) };
    }
};

proto.async = function ( this_val, args ) {
    if ( typeof this.$Concurrent_Thread_compiled != "function" ) throw new Error("this is not a compiled function");
    if ( args === void 0 ) args = [];  // IE6 does not allow null or undefined-value as the second argument of Function.prototype.apply. That does not conform to ECMA262-3!
    return new THREAD(
        this.$Concurrent_Thread_compiled(
            this_val,
            args,
            initial_continuation
        )
    );
};

            return {
                Thread: Thread
            };
        }();
    }
}
}.call(null) ) {
    this.Concurrent.Thread = Thread;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Data.Cons.Util.last === undefined ) this.Data.Cons.Util.last = undefined;
    if ( this.Data.Cons.Util.adder === undefined ) this.Data.Cons.Util.adder = undefined;
    if ( this.Data.Cons.Util.concat === undefined ) this.Data.Cons.Util.concat = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Cons ) {
with ( Data.Cons.Util ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Data.Cons code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Data.Cons.Util';

function last ( c ) {
    if ( !(c instanceof Cell) ) throw new TypeError("argument is not cons-list");
    if ( c.isNil() ) return c;
    if ( !(c.cdr instanceof Cell) ) throw new TypeError("argument is not cons-list");
    while ( !c.cdr.isNil() ) {
        c = c.cdr;
        if ( !(c.cdr instanceof Cell) ) throw new TypeError("argument is not cons-list");
    }
    return c;
}

function adder ( c ) {
    c = last(c);
    if ( c.isNil() ) throw new IllegalStateError("can't append to nil");
    return function ( /* variable arguments */ ) {
        c = last(c);
        for ( var i=0;  i < arguments.length;  i++ ) {
            c = c.cdr = new Cell(arguments[i], c.cdr);
        }
    };
}

function concat ( /* variable arguments */ ) {
    if ( arguments.length == 0 ) return nil();
    var head = arguments[0];
    var cell = last(head);
    for ( var i=1;  i < arguments.length;  i++ ) {
        cell.cdr = arguments[i];
        cell = last(cell);
    }
    return head;
}

            return {
                adder: adder, concat: concat, last: last
            };
        }();
    }
}
}
}.call(null) ) {
    this.Data.Cons.Util.adder = adder;
    this.Data.Cons.Util.concat = concat;
    this.Data.Cons.Util.last = last;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Concurrent.Thread.Compiler.Kit || (typeof this.Concurrent.Thread.Compiler.Kit != 'object' && typeof this.Concurrent.Thread.Compiler.Kit != 'function') ) this.Concurrent.Thread.Compiler.Kit = new Object();
    if ( this.Concurrent.Thread.Compiler.Kit.printTrees === undefined ) this.Concurrent.Thread.Compiler.Kit.printTrees = undefined;
    if ( this.Concurrent.Thread.Compiler.Kit.codeBug === undefined ) this.Concurrent.Thread.Compiler.Kit.codeBug = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler.Kit ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Igor Bukanov, igor@fastmail.fm
 *   Daisuke Maki
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * This file is based on the file Kit.java in Rhino 1.6R5.
 */

NAMESPACE = 'Concurrent.Thread.Compiler.Kit';

var printTrees = false;  // debug flag

function codeBug ( /* variable arguments */ ) {
    var str = "";
    for ( var i=0;  i < arguments.length;  i++ ) str += arguments[i];
    var e = new Data.Error.IllegalStateError("FAILED ASSERTION: " + str);
    var s = e.toString();
    if ( e.stack ) s += "\n----------\n" + e.stack;
    alert(s);
    throw e;
}

            return {
                printTrees: printTrees, codeBug: codeBug
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.Kit.printTrees = printTrees;
    this.Concurrent.Thread.Compiler.Kit.codeBug = codeBug;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( this.Concurrent.Thread.Compiler.IdentifierSet === undefined ) this.Concurrent.Thread.Compiler.IdentifierSet = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var MIN_INT = Math.pow(-2, 53);

function IdentifierSet ( ) {
    this._set      = {};
    this._state_no = MIN_INT;
}

var proto = IdentifierSet.prototype = new Set();
proto.constructor = IdentifierSet;

var hasOwnProperty = Object.prototype.hasOwnProperty;

proto.contains = function ( /* variable arguments */ ) {
    for ( var i=0;  i < arguments.length;  i++ ) {
        var id = arguments[i];
        if ( !(id instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
        // Because "hasOwnProperty" itself can be used as identifier,
        // we need to avoid "this._set.hasOwnProperty".
        if ( !hasOwnProperty.call(this._set, id.valueOf()) ) return false;
    }
    return true;
};

proto.add = function ( /* variable arguments */ ) {
    var changed = false;
    for ( var i=0;  i < arguments.length;  i++ ) {
        var id = arguments[i];
        if ( !(id instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
        var p = id.valueOf();
        if ( this._set[p] !== id ) {
            this._set[p] = id;
            this._state_no++;
            changed = true;
        }
    }
    return changed;
};

proto.remove = function ( /* variable arguments */ ) {
    var changed = false;
    for ( var i=0;  i < arguments.length;  i++ ) {
        var id = arguments[i];
        if ( !(id instanceof Identifier) ) throw new TypeError("argument is not of type Identifier");
        var p = id.valueOf();
        if ( hasOwnProperty.call(this._set, p) ) {
            delete this._set[p];
            this._state_no++;
            changed = true;
        }
    }
    return changed;
};

proto.toArray = function ( ) {
    var arr = [];
    for ( var i in this._set ) {
        if ( hasOwnProperty.call(this._set, i) ) arr.push(this._set[i]);
    }
    return arr;
};

proto.iterator = function ( ) {
    return new IdIterator(this, this.toArray(), 0);
};

function IdIterator ( parent, elems, index ) {
    this._parent = parent;
    this._elems  = elems;
    this._index  = index;
    this._state_no = parent._state_no;
}

var proto = IdIterator.prototype = new Iterator();
proto.constructor = IdIterator;

proto.isBoundTo = function ( o ) {
    return this._parent === o;
};

proto.isTail = function ( ) {
    if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
    return this._index >= this._elems.length;
};

proto.next = function ( ) {
    if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
    if ( this.isTail() ) throw new NoSuchElementError("no more element after the tail");
    return new IdIterator(this._parent, this._elems, this._index+1);
};

proto.value = function ( ) {
    if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
    return this._elems[this._index];
};

            return {
                IdentifierSet: IdentifierSet
            };
        }();
    }
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.IdentifierSet = IdentifierSet;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Continuation || (typeof this.Concurrent.Thread.Continuation != 'object' && typeof this.Concurrent.Thread.Continuation != 'function') ) this.Concurrent.Thread.Continuation = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( this.Concurrent.Thread.Continuation.callcc === undefined ) this.Concurrent.Thread.Continuation.callcc = undefined;
    if ( this.Concurrent.Thread.Continuation.getCC === undefined ) this.Concurrent.Thread.Continuation.getCC = undefined;
    if ( this.Concurrent.Thread.Continuation.currentContinuation === undefined ) this.Concurrent.Thread.Continuation.currentContinuation = undefined;
    if ( this.Concurrent.Thread.Continuation.ContinuationCalledException === undefined ) this.Concurrent.Thread.Continuation.ContinuationCalledException = undefined;
with ( function(){
with ( Data.Error ) {
with ( Concurrent.Thread.Continuation ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Continuation';

function callcc ( ) {
    throw new Error("can't call `" + NAMESPACE + ".callcc' in non-threaded functions");
}

callcc.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    function continuation ( ) {
        throw new Error("can't call any captured continuation in non-threaded functions");
    }
    continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
        return { continuation: $cont ,
                 timeout     : void 0,
                 ret_val     : $args[0] };
    };
    var f = $args[0];
    return f && typeof f.$Concurrent_Thread_compiled === "function"
             ?  f.$Concurrent_Thread_compiled(null, [continuation], $cont)
             :  {continuation:$cont, ret_val:f(continuation), timeout:void 0};
};

function getCC ( ) {
    throw new Error("can't call `" + NAMESPACE + ".getCC' in non-threaded functions");
}

getCC.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    function continuation ( ) {
        throw new Error("can't call any captured continuation in non-threaded functions");
    }
    continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
        return { continuation: $cont ,
                 timeout     : void 0,
                 ret_val     : $args[0] };
    };
    return {continuation:$cont, ret_val:continuation, timeout:void 0};
};

function currentContinuation ( ) {
    throw new Error("can't call `" + NAMESPACE + ".currentContinuation' in non-threaded functions");
}

currentContinuation.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    function continuation ( ) {
        throw new Error("can't call any captured continuation in non-threaded functions");
    }
    continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
        return { continuation: $cont.exception,
                 timeout     : void 0          ,
                 ret_val     : new ContinuationCalledException($args) };
    };
    return { continuation: $cont ,
             timeout     : void 0,
             ret_val     : continuation };
};

var ContinuationCalledException = Exception.extend(
    function ( $super, args ) {
        $super("continuation called");
        this.args = args;
    },
    { name: NAMESPACE + ".ContinuationCalledException" }
);

            return {
                ContinuationCalledException: ContinuationCalledException, callcc: callcc, getCC: getCC, currentContinuation: currentContinuation
            };
        }();
    }
}
}.call(null) ) {
    this.Concurrent.Thread.Continuation.ContinuationCalledException = ContinuationCalledException;
    this.Concurrent.Thread.Continuation.callcc = callcc;
    this.Concurrent.Thread.Continuation.getCC = getCC;
    this.Concurrent.Thread.Continuation.currentContinuation = currentContinuation;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( this.Concurrent.Thread.Compiler.ErrorReporter === undefined ) this.Concurrent.Thread.Compiler.ErrorReporter = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Norris Boyd
 *   Daisuke Maki
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * This file is based on the file ErrorReporter.java in Rhino 1.6R5.
 */

// API class

NAMESPACE = 'Concurrent.Thread.Compiler';

/**
 * This is interface defines a protocol for the reporting of
 * errors during JavaScript translation or execution.
 *
 * @author Norris Boyd
 */

function ErrorReporter ( ) {
    // This is kind of abstract class.
    // It provides null-implementations for the methods as default.
}

var proto = ErrorReporter.prototype;

/**
 * Report a warning.
 *
 * The implementing class may choose to ignore the warning
 * if it desires.
 *
 * @param message a String describing the warning
 * @param line the line number associated with the warning
 * @param lineSource the text of the line (may be null)
 * @param lineOffset the offset into lineSource where problem was detected
 */
proto.warning = function ( message, line, lineSource, lineOffset ) { };

/**
 * Report an error.
 *
 * The implementing class is free to throw an exception if
 * it desires.
 *
 * If execution has not yet begun, the JavaScript engine is
 * free to find additional errors rather than terminating
 * the translation. It will not execute a script that had
 * errors, however.
 *
 * @param message a String describing the error
 * @param line the line number associated with the error
 * @param lineSource the text of the line (may be null)
 * @param lineOffset the offset into lineSource where problem was detected
 */
proto.error   = function ( message, line, lineSource, lineOffset ) { };

            return {
                ErrorReporter: ErrorReporter
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.ErrorReporter = ErrorReporter;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( this.Concurrent.Thread.Compiler.isAlpha === undefined ) this.Concurrent.Thread.Compiler.isAlpha = undefined;
    if ( this.Concurrent.Thread.Compiler.isDigit === undefined ) this.Concurrent.Thread.Compiler.isDigit = undefined;
    if ( this.Concurrent.Thread.Compiler.isHexDigit === undefined ) this.Concurrent.Thread.Compiler.isHexDigit = undefined;
    if ( this.Concurrent.Thread.Compiler.isLineTerminator === undefined ) this.Concurrent.Thread.Compiler.isLineTerminator = undefined;
    if ( this.Concurrent.Thread.Compiler.isSpace === undefined ) this.Concurrent.Thread.Compiler.isSpace = undefined;
    if ( this.Concurrent.Thread.Compiler.isFormatChar === undefined ) this.Concurrent.Thread.Compiler.isFormatChar = undefined;
    if ( this.Concurrent.Thread.Compiler.isIdentifierStart === undefined ) this.Concurrent.Thread.Compiler.isIdentifierStart = undefined;
    if ( this.Concurrent.Thread.Compiler.isIdentifierPart === undefined ) this.Concurrent.Thread.Compiler.isIdentifierPart = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

function isAlpha ( c )
{
    c = c.charCodeAt(0);
    // #generated# Last update: Tue, 01 Aug 2006 16:31:50 +0900
    return c <= 0x5A ?
    0x41 <= c :
    0x61 <= c && c <= 0x7A;
    // #/generated#
}

function isDigit ( c )
{
    c = c.charCodeAt(0);
    // #generated# Last update: Tue, 01 Aug 2006 21:02:15 +0900
    return 0x30 <= c && c <= 0x39;
    // #/generated#
}

function isHexDigit  ( c )
{
    c = c.charCodeAt(0);
    // #generated# Last update: Tue, 01 Aug 2006 15:49:52 +0900
    return c <= 0x46 ?
    c <= 0x39 ?
    0x30 <= c :
    0x41 <= c :
    0x61 <= c && c <= 0x66;
    // #/generated#
}

function isLineTerminator ( c ) {
    switch ( c.charCodeAt(0) ) {
    case 0x000A:  // Line Feed           <LF>
    case 0x000D:  // Carriage Return     <CR>
    case 0x2028:  // Line separator      <LS>
    case 0x2029:  // Paragraph separator <PS>
        return true;
    default:
        return false;
    }
}

function isSpace ( c )
{
    c = c.charCodeAt(0);
    if ( c <= 255 ) {
        switch ( c ) {
        case 0x0009:  // Tab            <TAB>
        case 0x000B:  // Vertical Tab   <VT>
        case 0x000C:  // Form Feed      <FF>
        case 0x0020:  // Space          <SP>
        case 0x00A0:  // No-break space <NBSP>
            return true;
        default:
            return false;
        }
    }
    else {
        // the following code is derived from the Unicode category Zs based on:
        // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
        // #generated# Last update: Tue, 01 Aug 2006 01:57:18 +0900
        return c <= 0x180E ?
        c <= 0xA0 ?
        c <= 0x20 ?
        0x20 <= c :
        0xA0 <= c :
        c <= 0x1680 ?
        0x1680 <= c :
        0x180E <= c :
        c <= 0x202F ?
        c <= 0x200A ?
        0x2000 <= c :
        0x202F <= c :
        c <= 0x205F ?
        0x205F <= c :
        c === 0x3000;
        // #/generated#
    }
}

function isFormatChar ( c )
{
    c = c.charCodeAt(0);
    if ( c <= 127 ) return false;  // optimization for ASCII characters
    // the following code is derived from the Unicode category Cf based on:
    // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
    // #generated# Last update: Tue, 01 Aug 2006 01:50:39 +0900
    return c <= 0x202E ?
    c <= 0x70F ?
    c <= 0x603 ?
    c <= 0xAD ?
    0xAD <= c :
    0x600 <= c :
    c <= 0x6DD ?
    0x6DD <= c :
    0x70F <= c :
    c <= 0x200F ?
    c <= 0x17B5 ?
    0x17B4 <= c :
    0x200B <= c :
    0x202A <= c :
    c <= 0xFFFB ?
    c <= 0x206F ?
    c <= 0x2063 ?
    0x2060 <= c :
    0x206A <= c :
    c <= 0xFEFF ?
    0xFEFF <= c :
    0xFFF9 <= c :
    c <= 0xE0001 ?
    c <= 0x1D17A ?
    0x1D173 <= c :
    0xE0001 <= c :
    0xE0020 <= c && c <= 0xE007F;
    // #/generated#
}

function isIdentifierStart ( c ) {
    var c = c.charCodeAt(0);
    switch ( c ) {
    case 0x24:  // '$'
    case 0x5F:  // '_'
        return true;
    }
    // the following code is derived from the Unicode category Lu, Ll, Lt, Lm, Lo, and Nl based on:
    // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
    // #generated# Last update: Tue, 01 Aug 2006 01:47:30 +0900
    return c <= 0x1731 ?
    c <= 0xB95 ?
    c <= 0x961 ?
    c <= 0x587 ?
    c <= 0x37D ?
    c <= 0xD6 ?
    c <= 0xAA ?
    c <= 0x7A ?
    c <= 0x5A ?
    0x41 <= c :
    0x61 <= c :
    0xAA <= c :
    c <= 0xBA ?
    c <= 0xB5 ?
    0xB5 <= c :
    0xBA <= c :
    0xC0 <= c :
    c <= 0x2D1 ?
    c <= 0x2C1 ?
    c <= 0xF6 ?
    0xD8 <= c :
    0xF8 <= c :
    0x2C6 <= c :
    c <= 0x2EE ?
    c <= 0x2E4 ?
    0x2E0 <= c :
    0x2EE <= c :
    0x37A <= c :
    c <= 0x3F5 ?
    c <= 0x38C ?
    c <= 0x38A ?
    c <= 0x386 ?
    0x386 <= c :
    0x388 <= c :
    0x38C <= c :
    c <= 0x3CE ?
    c <= 0x3A1 ?
    0x38E <= c :
    0x3A3 <= c :
    0x3D0 <= c :
    c <= 0x556 ?
    c <= 0x513 ?
    c <= 0x481 ?
    0x3F7 <= c :
    0x48A <= c :
    0x531 <= c :
    c <= 0x559 ?
    0x559 <= c :
    0x561 <= c :
    c <= 0x710 ?
    c <= 0x6D3 ?
    c <= 0x63A ?
    c <= 0x5F2 ?
    c <= 0x5EA ?
    0x5D0 <= c :
    0x5F0 <= c :
    0x621 <= c :
    c <= 0x66F ?
    c <= 0x64A ?
    0x640 <= c :
    0x66E <= c :
    0x671 <= c :
    c <= 0x6EF ?
    c <= 0x6E6 ?
    c <= 0x6D5 ?
    0x6D5 <= c :
    0x6E5 <= c :
    0x6EE <= c :
    c <= 0x6FF ?
    c <= 0x6FC ?
    0x6FA <= c :
    0x6FF <= c :
    0x710 <= c :
    c <= 0x7F5 ?
    c <= 0x7A5 ?
    c <= 0x76D ?
    c <= 0x72F ?
    0x712 <= c :
    0x74D <= c :
    0x780 <= c :
    c <= 0x7EA ?
    c <= 0x7B1 ?
    0x7B1 <= c :
    0x7CA <= c :
    0x7F4 <= c :
    c <= 0x93D ?
    c <= 0x939 ?
    c <= 0x7FA ?
    0x7FA <= c :
    0x904 <= c :
    0x93D <= c :
    c <= 0x950 ?
    0x950 <= c :
    0x958 <= c :
    c <= 0xA8D ?
    c <= 0x9F1 ?
    c <= 0x9B2 ?
    c <= 0x990 ?
    c <= 0x98C ?
    c <= 0x97F ?
    0x97B <= c :
    0x985 <= c :
    0x98F <= c :
    c <= 0x9B0 ?
    c <= 0x9A8 ?
    0x993 <= c :
    0x9AA <= c :
    0x9B2 <= c :
    c <= 0x9CE ?
    c <= 0x9BD ?
    c <= 0x9B9 ?
    0x9B6 <= c :
    0x9BD <= c :
    0x9CE <= c :
    c <= 0x9E1 ?
    c <= 0x9DD ?
    0x9DC <= c :
    0x9DF <= c :
    0x9F0 <= c :
    c <= 0xA36 ?
    c <= 0xA28 ?
    c <= 0xA10 ?
    c <= 0xA0A ?
    0xA05 <= c :
    0xA0F <= c :
    0xA13 <= c :
    c <= 0xA33 ?
    c <= 0xA30 ?
    0xA2A <= c :
    0xA32 <= c :
    0xA35 <= c :
    c <= 0xA5E ?
    c <= 0xA5C ?
    c <= 0xA39 ?
    0xA38 <= c :
    0xA59 <= c :
    0xA5E <= c :
    c <= 0xA74 ?
    0xA72 <= c :
    0xA85 <= c :
    c <= 0xB28 ?
    c <= 0xABD ?
    c <= 0xAB0 ?
    c <= 0xAA8 ?
    c <= 0xA91 ?
    0xA8F <= c :
    0xA93 <= c :
    0xAAA <= c :
    c <= 0xAB9 ?
    c <= 0xAB3 ?
    0xAB2 <= c :
    0xAB5 <= c :
    0xABD <= c :
    c <= 0xB0C ?
    c <= 0xAE1 ?
    c <= 0xAD0 ?
    0xAD0 <= c :
    0xAE0 <= c :
    0xB05 <= c :
    c <= 0xB10 ?
    0xB0F <= c :
    0xB13 <= c :
    c <= 0xB61 ?
    c <= 0xB39 ?
    c <= 0xB33 ?
    c <= 0xB30 ?
    0xB2A <= c :
    0xB32 <= c :
    0xB35 <= c :
    c <= 0xB5D ?
    c <= 0xB3D ?
    0xB3D <= c :
    0xB5C <= c :
    0xB5F <= c :
    c <= 0xB8A ?
    c <= 0xB83 ?
    c <= 0xB71 ?
    0xB71 <= c :
    0xB83 <= c :
    0xB85 <= c :
    c <= 0xB90 ?
    0xB8E <= c :
    0xB92 <= c :
    c <= 0xEB0 ?
    c <= 0xD28 ?
    c <= 0xC61 ?
    c <= 0xBB9 ?
    c <= 0xB9F ?
    c <= 0xB9C ?
    c <= 0xB9A ?
    0xB99 <= c :
    0xB9C <= c :
    0xB9E <= c :
    c <= 0xBAA ?
    c <= 0xBA4 ?
    0xBA3 <= c :
    0xBA8 <= c :
    0xBAE <= c :
    c <= 0xC28 ?
    c <= 0xC10 ?
    c <= 0xC0C ?
    0xC05 <= c :
    0xC0E <= c :
    0xC12 <= c :
    c <= 0xC39 ?
    c <= 0xC33 ?
    0xC2A <= c :
    0xC35 <= c :
    0xC60 <= c :
    c <= 0xCBD ?
    c <= 0xCA8 ?
    c <= 0xC90 ?
    c <= 0xC8C ?
    0xC85 <= c :
    0xC8E <= c :
    0xC92 <= c :
    c <= 0xCB9 ?
    c <= 0xCB3 ?
    0xCAA <= c :
    0xCB5 <= c :
    0xCBD <= c :
    c <= 0xD0C ?
    c <= 0xCE1 ?
    c <= 0xCDE ?
    0xCDE <= c :
    0xCE0 <= c :
    0xD05 <= c :
    c <= 0xD10 ?
    0xD0E <= c :
    0xD12 <= c :
    c <= 0xE82 ?
    c <= 0xDBD ?
    c <= 0xD96 ?
    c <= 0xD61 ?
    c <= 0xD39 ?
    0xD2A <= c :
    0xD60 <= c :
    0xD85 <= c :
    c <= 0xDBB ?
    c <= 0xDB1 ?
    0xD9A <= c :
    0xDB3 <= c :
    0xDBD <= c :
    c <= 0xE33 ?
    c <= 0xE30 ?
    c <= 0xDC6 ?
    0xDC0 <= c :
    0xE01 <= c :
    0xE32 <= c :
    c <= 0xE46 ?
    0xE40 <= c :
    0xE81 <= c :
    c <= 0xE9F ?
    c <= 0xE8A ?
    c <= 0xE88 ?
    c <= 0xE84 ?
    0xE84 <= c :
    0xE87 <= c :
    0xE8A <= c :
    c <= 0xE97 ?
    c <= 0xE8D ?
    0xE8D <= c :
    0xE94 <= c :
    0xE99 <= c :
    c <= 0xEA7 ?
    c <= 0xEA5 ?
    c <= 0xEA3 ?
    0xEA1 <= c :
    0xEA5 <= c :
    0xEA7 <= c :
    c <= 0xEAB ?
    0xEAA <= c :
    0xEAD <= c :
    c <= 0x1258 ?
    c <= 0x102A ?
    c <= 0xF00 ?
    c <= 0xEC4 ?
    c <= 0xEBD ?
    c <= 0xEB3 ?
    0xEB2 <= c :
    0xEBD <= c :
    0xEC0 <= c :
    c <= 0xEDD ?
    c <= 0xEC6 ?
    0xEC6 <= c :
    0xEDC <= c :
    0xF00 <= c :
    c <= 0xF8B ?
    c <= 0xF6A ?
    c <= 0xF47 ?
    0xF40 <= c :
    0xF49 <= c :
    0xF88 <= c :
    c <= 0x1027 ?
    c <= 0x1021 ?
    0x1000 <= c :
    0x1023 <= c :
    0x1029 <= c :
    c <= 0x11A2 ?
    c <= 0x10FA ?
    c <= 0x10C5 ?
    c <= 0x1055 ?
    0x1050 <= c :
    0x10A0 <= c :
    0x10D0 <= c :
    c <= 0x1159 ?
    c <= 0x10FC ?
    0x10FC <= c :
    0x1100 <= c :
    0x115F <= c :
    c <= 0x124D ?
    c <= 0x1248 ?
    c <= 0x11F9 ?
    0x11A8 <= c :
    0x1200 <= c :
    0x124A <= c :
    c <= 0x1256 ?
    0x1250 <= c :
    0x1258 <= c :
    c <= 0x1315 ?
    c <= 0x12BE ?
    c <= 0x128D ?
    c <= 0x1288 ?
    c <= 0x125D ?
    0x125A <= c :
    0x1260 <= c :
    0x128A <= c :
    c <= 0x12B5 ?
    c <= 0x12B0 ?
    0x1290 <= c :
    0x12B2 <= c :
    0x12B8 <= c :
    c <= 0x12D6 ?
    c <= 0x12C5 ?
    c <= 0x12C0 ?
    0x12C0 <= c :
    0x12C2 <= c :
    0x12C8 <= c :
    c <= 0x1310 ?
    0x12D8 <= c :
    0x1312 <= c :
    c <= 0x169A ?
    c <= 0x13F4 ?
    c <= 0x138F ?
    c <= 0x135A ?
    0x1318 <= c :
    0x1380 <= c :
    0x13A0 <= c :
    c <= 0x1676 ?
    c <= 0x166C ?
    0x1401 <= c :
    0x166F <= c :
    0x1681 <= c :
    c <= 0x170C ?
    c <= 0x16F0 ?
    c <= 0x16EA ?
    0x16A0 <= c :
    0x16EE <= c :
    0x1700 <= c :
    c <= 0x1711 ?
    0x170E <= c :
    0x1720 <= c :
    c <= 0xA805 ?
    c <= 0x2115 ?
    c <= 0x1F4D ?
    c <= 0x19A9 ?
    c <= 0x17DC ?
    c <= 0x1770 ?
    c <= 0x176C ?
    c <= 0x1751 ?
    0x1740 <= c :
    0x1760 <= c :
    0x176E <= c :
    c <= 0x17D7 ?
    c <= 0x17B3 ?
    0x1780 <= c :
    0x17D7 <= c :
    0x17DC <= c :
    c <= 0x191C ?
    c <= 0x18A8 ?
    c <= 0x1877 ?
    0x1820 <= c :
    0x1880 <= c :
    0x1900 <= c :
    c <= 0x1974 ?
    c <= 0x196D ?
    0x1950 <= c :
    0x1970 <= c :
    0x1980 <= c :
    c <= 0x1E9B ?
    c <= 0x1B33 ?
    c <= 0x1A16 ?
    c <= 0x19C7 ?
    0x19C1 <= c :
    0x1A00 <= c :
    0x1B05 <= c :
    c <= 0x1DBF ?
    c <= 0x1B4B ?
    0x1B45 <= c :
    0x1D00 <= c :
    0x1E00 <= c :
    c <= 0x1F1D ?
    c <= 0x1F15 ?
    c <= 0x1EF9 ?
    0x1EA0 <= c :
    0x1F00 <= c :
    0x1F18 <= c :
    c <= 0x1F45 ?
    0x1F20 <= c :
    0x1F48 <= c :
    c <= 0x1FD3 ?
    c <= 0x1FB4 ?
    c <= 0x1F5B ?
    c <= 0x1F59 ?
    c <= 0x1F57 ?
    0x1F50 <= c :
    0x1F59 <= c :
    0x1F5B <= c :
    c <= 0x1F7D ?
    c <= 0x1F5D ?
    0x1F5D <= c :
    0x1F5F <= c :
    0x1F80 <= c :
    c <= 0x1FC4 ?
    c <= 0x1FBE ?
    c <= 0x1FBC ?
    0x1FB6 <= c :
    0x1FBE <= c :
    0x1FC2 <= c :
    c <= 0x1FCC ?
    0x1FC6 <= c :
    0x1FD0 <= c :
    c <= 0x207F ?
    c <= 0x1FF4 ?
    c <= 0x1FEC ?
    c <= 0x1FDB ?
    0x1FD6 <= c :
    0x1FE0 <= c :
    0x1FF2 <= c :
    c <= 0x2071 ?
    c <= 0x1FFC ?
    0x1FF6 <= c :
    0x2071 <= c :
    0x207F <= c :
    c <= 0x2107 ?
    c <= 0x2102 ?
    c <= 0x2094 ?
    0x2090 <= c :
    0x2102 <= c :
    0x2107 <= c :
    c <= 0x2113 ?
    0x210A <= c :
    0x2115 <= c :
    c <= 0x2DBE ?
    c <= 0x2C5E ?
    c <= 0x2139 ?
    c <= 0x2126 ?
    c <= 0x2124 ?
    c <= 0x211D ?
    0x2119 <= c :
    0x2124 <= c :
    0x2126 <= c :
    c <= 0x212D ?
    c <= 0x2128 ?
    0x2128 <= c :
    0x212A <= c :
    0x212F <= c :
    c <= 0x214E ?
    c <= 0x2149 ?
    c <= 0x213F ?
    0x213C <= c :
    0x2145 <= c :
    0x214E <= c :
    c <= 0x2C2E ?
    c <= 0x2184 ?
    0x2160 <= c :
    0x2C00 <= c :
    0x2C30 <= c :
    c <= 0x2D6F ?
    c <= 0x2CE4 ?
    c <= 0x2C77 ?
    c <= 0x2C6C ?
    0x2C60 <= c :
    0x2C74 <= c :
    0x2C80 <= c :
    c <= 0x2D65 ?
    c <= 0x2D25 ?
    0x2D00 <= c :
    0x2D30 <= c :
    0x2D6F <= c :
    c <= 0x2DAE ?
    c <= 0x2DA6 ?
    c <= 0x2D96 ?
    0x2D80 <= c :
    0x2DA0 <= c :
    0x2DA8 <= c :
    c <= 0x2DB6 ?
    0x2DB0 <= c :
    0x2DB8 <= c :
    c <= 0x30FA ?
    c <= 0x3029 ?
    c <= 0x2DD6 ?
    c <= 0x2DCE ?
    c <= 0x2DC6 ?
    0x2DC0 <= c :
    0x2DC8 <= c :
    0x2DD0 <= c :
    c <= 0x3007 ?
    c <= 0x2DDE ?
    0x2DD8 <= c :
    0x3005 <= c :
    0x3021 <= c :
    c <= 0x3096 ?
    c <= 0x303C ?
    c <= 0x3035 ?
    0x3031 <= c :
    0x3038 <= c :
    0x3041 <= c :
    c <= 0x309F ?
    0x309D <= c :
    0x30A1 <= c :
    c <= 0x4DB5 ?
    c <= 0x318E ?
    c <= 0x312C ?
    c <= 0x30FF ?
    0x30FC <= c :
    0x3105 <= c :
    0x3131 <= c :
    c <= 0x31FF ?
    c <= 0x31B7 ?
    0x31A0 <= c :
    0x31F0 <= c :
    0x3400 <= c :
    c <= 0xA71A ?
    c <= 0xA48C ?
    c <= 0x9FBB ?
    0x4E00 <= c :
    0xA000 <= c :
    0xA717 <= c :
    c <= 0xA801 ?
    0xA800 <= c :
    0xA803 <= c :
    c <= 0x1049D ?
    c <= 0xFEFC ?
    c <= 0xFB36 ?
    c <= 0xFA6A ?
    c <= 0xA873 ?
    c <= 0xA822 ?
    c <= 0xA80A ?
    0xA807 <= c :
    0xA80C <= c :
    0xA840 <= c :
    c <= 0xFA2D ?
    c <= 0xD7A3 ?
    0xAC00 <= c :
    0xF900 <= c :
    0xFA30 <= c :
    c <= 0xFB17 ?
    c <= 0xFB06 ?
    c <= 0xFAD9 ?
    0xFA70 <= c :
    0xFB00 <= c :
    0xFB13 <= c :
    c <= 0xFB28 ?
    c <= 0xFB1D ?
    0xFB1D <= c :
    0xFB1F <= c :
    0xFB2A <= c :
    c <= 0xFD3D ?
    c <= 0xFB41 ?
    c <= 0xFB3E ?
    c <= 0xFB3C ?
    0xFB38 <= c :
    0xFB3E <= c :
    0xFB40 <= c :
    c <= 0xFBB1 ?
    c <= 0xFB44 ?
    0xFB43 <= c :
    0xFB46 <= c :
    0xFBD3 <= c :
    c <= 0xFDFB ?
    c <= 0xFDC7 ?
    c <= 0xFD8F ?
    0xFD50 <= c :
    0xFD92 <= c :
    0xFDF0 <= c :
    c <= 0xFE74 ?
    0xFE70 <= c :
    0xFE76 <= c :
    c <= 0x1003D ?
    c <= 0xFFD7 ?
    c <= 0xFFBE ?
    c <= 0xFF5A ?
    c <= 0xFF3A ?
    0xFF21 <= c :
    0xFF41 <= c :
    0xFF66 <= c :
    c <= 0xFFCF ?
    c <= 0xFFC7 ?
    0xFFC2 <= c :
    0xFFCA <= c :
    0xFFD2 <= c :
    c <= 0x10026 ?
    c <= 0x1000B ?
    c <= 0xFFDC ?
    0xFFDA <= c :
    0x10000 <= c :
    0x1000D <= c :
    c <= 0x1003A ?
    0x10028 <= c :
    0x1003C <= c :
    c <= 0x1034A ?
    c <= 0x100FA ?
    c <= 0x1005D ?
    c <= 0x1004D ?
    0x1003F <= c :
    0x10050 <= c :
    0x10080 <= c :
    c <= 0x1031E ?
    c <= 0x10174 ?
    0x10140 <= c :
    0x10300 <= c :
    0x10330 <= c :
    c <= 0x103CF ?
    c <= 0x103C3 ?
    c <= 0x1039D ?
    0x10380 <= c :
    0x103A0 <= c :
    0x103C8 <= c :
    c <= 0x103D5 ?
    0x103D1 <= c :
    0x10400 <= c :
    c <= 0x1D505 ?
    c <= 0x1236E ?
    c <= 0x1083F ?
    c <= 0x10835 ?
    c <= 0x10808 ?
    c <= 0x10805 ?
    0x10800 <= c :
    0x10808 <= c :
    0x1080A <= c :
    c <= 0x1083C ?
    c <= 0x10838 ?
    0x10837 <= c :
    0x1083C <= c :
    0x1083F <= c :
    c <= 0x10A13 ?
    c <= 0x10A00 ?
    c <= 0x10915 ?
    0x10900 <= c :
    0x10A00 <= c :
    0x10A10 <= c :
    c <= 0x10A33 ?
    c <= 0x10A17 ?
    0x10A15 <= c :
    0x10A19 <= c :
    0x12000 <= c :
    c <= 0x1D4A6 ?
    c <= 0x1D49C ?
    c <= 0x1D454 ?
    c <= 0x12462 ?
    0x12400 <= c :
    0x1D400 <= c :
    0x1D456 <= c :
    c <= 0x1D4A2 ?
    c <= 0x1D49F ?
    0x1D49E <= c :
    0x1D4A2 <= c :
    0x1D4A5 <= c :
    c <= 0x1D4BB ?
    c <= 0x1D4B9 ?
    c <= 0x1D4AC ?
    0x1D4A9 <= c :
    0x1D4AE <= c :
    0x1D4BB <= c :
    c <= 0x1D4C3 ?
    0x1D4BD <= c :
    0x1D4C5 <= c :
    c <= 0x1D6DA ?
    c <= 0x1D544 ?
    c <= 0x1D51C ?
    c <= 0x1D514 ?
    c <= 0x1D50A ?
    0x1D507 <= c :
    0x1D50D <= c :
    0x1D516 <= c :
    c <= 0x1D53E ?
    c <= 0x1D539 ?
    0x1D51E <= c :
    0x1D53B <= c :
    0x1D540 <= c :
    c <= 0x1D6A5 ?
    c <= 0x1D550 ?
    c <= 0x1D546 ?
    0x1D546 <= c :
    0x1D54A <= c :
    0x1D552 <= c :
    c <= 0x1D6C0 ?
    0x1D6A8 <= c :
    0x1D6C2 <= c :
    c <= 0x1D788 ?
    c <= 0x1D734 ?
    c <= 0x1D714 ?
    c <= 0x1D6FA ?
    0x1D6DC <= c :
    0x1D6FC <= c :
    0x1D716 <= c :
    c <= 0x1D76E ?
    c <= 0x1D74E ?
    0x1D736 <= c :
    0x1D750 <= c :
    0x1D770 <= c :
    c <= 0x1D7CB ?
    c <= 0x1D7C2 ?
    c <= 0x1D7A8 ?
    0x1D78A <= c :
    0x1D7AA <= c :
    0x1D7C4 <= c :
    c <= 0x2A6D6 ?
    0x20000 <= c :
    0x2F800 <= c && c <= 0x2FA1D;
    // #/generated#
}

function isIdentifierPart ( c ) {
    var c = c.charCodeAt(0);
    switch ( c ) {
    case 0x24:  // '$'
    case 0x5F:  // '_'
        return true;
    }
    // the following code is derived from the Unicode category Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, and Pc based on:
    // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
    // #generated# Last update: Tue, 01 Aug 2006 02:00:01 +0900
    return c <= 0x12B0 ?
    c <= 0xB90 ?
    c <= 0x990 ?
    c <= 0x5BF ?
    c <= 0x37D ?
    c <= 0xD6 ?
    c <= 0x7A ?
    c <= 0x5A ?
    c <= 0x39 ?
    0x30 <= c :
    0x41 <= c :
    c <= 0x5F ?
    0x5F <= c :
    0x61 <= c :
    c <= 0xB5 ?
    c <= 0xAA ?
    0xAA <= c :
    0xB5 <= c :
    c <= 0xBA ?
    0xBA <= c :
    0xC0 <= c :
    c <= 0x2E4 ?
    c <= 0x2C1 ?
    c <= 0xF6 ?
    0xD8 <= c :
    0xF8 <= c :
    c <= 0x2D1 ?
    0x2C6 <= c :
    0x2E0 <= c :
    c <= 0x36F ?
    c <= 0x2EE ?
    0x2EE <= c :
    0x300 <= c :
    0x37A <= c :
    c <= 0x481 ?
    c <= 0x3A1 ?
    c <= 0x38A ?
    c <= 0x386 ?
    0x386 <= c :
    0x388 <= c :
    c <= 0x38C ?
    0x38C <= c :
    0x38E <= c :
    c <= 0x3F5 ?
    c <= 0x3CE ?
    0x3A3 <= c :
    0x3D0 <= c :
    0x3F7 <= c :
    c <= 0x559 ?
    c <= 0x513 ?
    c <= 0x486 ?
    0x483 <= c :
    0x48A <= c :
    c <= 0x556 ?
    0x531 <= c :
    0x559 <= c :
    c <= 0x5BD ?
    c <= 0x587 ?
    0x561 <= c :
    0x591 <= c :
    0x5BF <= c :
    c <= 0x6FF ?
    c <= 0x63A ?
    c <= 0x5EA ?
    c <= 0x5C5 ?
    c <= 0x5C2 ?
    0x5C1 <= c :
    0x5C4 <= c :
    c <= 0x5C7 ?
    0x5C7 <= c :
    0x5D0 <= c :
    c <= 0x615 ?
    c <= 0x5F2 ?
    0x5F0 <= c :
    0x610 <= c :
    0x621 <= c :
    c <= 0x6DC ?
    c <= 0x669 ?
    c <= 0x65E ?
    0x640 <= c :
    0x660 <= c :
    c <= 0x6D3 ?
    0x66E <= c :
    0x6D5 <= c :
    c <= 0x6FC ?
    c <= 0x6E8 ?
    0x6DF <= c :
    0x6EA <= c :
    0x6FF <= c :
    c <= 0x94D ?
    c <= 0x7F5 ?
    c <= 0x76D ?
    c <= 0x74A ?
    0x710 <= c :
    0x74D <= c :
    c <= 0x7B1 ?
    0x780 <= c :
    0x7C0 <= c :
    c <= 0x939 ?
    c <= 0x7FA ?
    0x7FA <= c :
    0x901 <= c :
    0x93C <= c :
    c <= 0x97F ?
    c <= 0x963 ?
    c <= 0x954 ?
    0x950 <= c :
    0x958 <= c :
    c <= 0x96F ?
    0x966 <= c :
    0x97B <= c :
    c <= 0x98C ?
    c <= 0x983 ?
    0x981 <= c :
    0x985 <= c :
    0x98F <= c :
    c <= 0xA91 ?
    c <= 0xA28 ?
    c <= 0x9D7 ?
    c <= 0x9B9 ?
    c <= 0x9B0 ?
    c <= 0x9A8 ?
    0x993 <= c :
    0x9AA <= c :
    c <= 0x9B2 ?
    0x9B2 <= c :
    0x9B6 <= c :
    c <= 0x9C8 ?
    c <= 0x9C4 ?
    0x9BC <= c :
    0x9C7 <= c :
    c <= 0x9CE ?
    0x9CB <= c :
    0x9D7 <= c :
    c <= 0xA03 ?
    c <= 0x9E3 ?
    c <= 0x9DD ?
    0x9DC <= c :
    0x9DF <= c :
    c <= 0x9F1 ?
    0x9E6 <= c :
    0xA01 <= c :
    c <= 0xA10 ?
    c <= 0xA0A ?
    0xA05 <= c :
    0xA0F <= c :
    0xA13 <= c :
    c <= 0xA48 ?
    c <= 0xA39 ?
    c <= 0xA33 ?
    c <= 0xA30 ?
    0xA2A <= c :
    0xA32 <= c :
    c <= 0xA36 ?
    0xA35 <= c :
    0xA38 <= c :
    c <= 0xA42 ?
    c <= 0xA3C ?
    0xA3C <= c :
    0xA3E <= c :
    0xA47 <= c :
    c <= 0xA74 ?
    c <= 0xA5C ?
    c <= 0xA4D ?
    0xA4B <= c :
    0xA59 <= c :
    c <= 0xA5E ?
    0xA5E <= c :
    0xA66 <= c :
    c <= 0xA8D ?
    c <= 0xA83 ?
    0xA81 <= c :
    0xA85 <= c :
    0xA8F <= c :
    c <= 0xB28 ?
    c <= 0xACD ?
    c <= 0xAB9 ?
    c <= 0xAB0 ?
    c <= 0xAA8 ?
    0xA93 <= c :
    0xAAA <= c :
    c <= 0xAB3 ?
    0xAB2 <= c :
    0xAB5 <= c :
    c <= 0xAC9 ?
    c <= 0xAC5 ?
    0xABC <= c :
    0xAC7 <= c :
    0xACB <= c :
    c <= 0xB03 ?
    c <= 0xAE3 ?
    c <= 0xAD0 ?
    0xAD0 <= c :
    0xAE0 <= c :
    c <= 0xAEF ?
    0xAE6 <= c :
    0xB01 <= c :
    c <= 0xB10 ?
    c <= 0xB0C ?
    0xB05 <= c :
    0xB0F <= c :
    0xB13 <= c :
    c <= 0xB57 ?
    c <= 0xB43 ?
    c <= 0xB33 ?
    c <= 0xB30 ?
    0xB2A <= c :
    0xB32 <= c :
    c <= 0xB39 ?
    0xB35 <= c :
    0xB3C <= c :
    c <= 0xB4D ?
    c <= 0xB48 ?
    0xB47 <= c :
    0xB4B <= c :
    0xB56 <= c :
    c <= 0xB71 ?
    c <= 0xB61 ?
    c <= 0xB5D ?
    0xB5C <= c :
    0xB5F <= c :
    c <= 0xB6F ?
    0xB66 <= c :
    0xB71 <= c :
    c <= 0xB8A ?
    c <= 0xB83 ?
    0xB82 <= c :
    0xB85 <= c :
    0xB8E <= c :
    c <= 0xDD6 ?
    c <= 0xCB3 ?
    c <= 0xC10 ?
    c <= 0xBC2 ?
    c <= 0xB9F ?
    c <= 0xB9A ?
    c <= 0xB95 ?
    0xB92 <= c :
    0xB99 <= c :
    c <= 0xB9C ?
    0xB9C <= c :
    0xB9E <= c :
    c <= 0xBAA ?
    c <= 0xBA4 ?
    0xBA3 <= c :
    0xBA8 <= c :
    c <= 0xBB9 ?
    0xBAE <= c :
    0xBBE <= c :
    c <= 0xBEF ?
    c <= 0xBCD ?
    c <= 0xBC8 ?
    0xBC6 <= c :
    0xBCA <= c :
    c <= 0xBD7 ?
    0xBD7 <= c :
    0xBE6 <= c :
    c <= 0xC0C ?
    c <= 0xC03 ?
    0xC01 <= c :
    0xC05 <= c :
    0xC0E <= c :
    c <= 0xC56 ?
    c <= 0xC44 ?
    c <= 0xC33 ?
    c <= 0xC28 ?
    0xC12 <= c :
    0xC2A <= c :
    c <= 0xC39 ?
    0xC35 <= c :
    0xC3E <= c :
    c <= 0xC4D ?
    c <= 0xC48 ?
    0xC46 <= c :
    0xC4A <= c :
    0xC55 <= c :
    c <= 0xC8C ?
    c <= 0xC6F ?
    c <= 0xC61 ?
    0xC60 <= c :
    0xC66 <= c :
    c <= 0xC83 ?
    0xC82 <= c :
    0xC85 <= c :
    c <= 0xCA8 ?
    c <= 0xC90 ?
    0xC8E <= c :
    0xC92 <= c :
    0xCAA <= c :
    c <= 0xD43 ?
    c <= 0xCE3 ?
    c <= 0xCCD ?
    c <= 0xCC4 ?
    c <= 0xCB9 ?
    0xCB5 <= c :
    0xCBC <= c :
    c <= 0xCC8 ?
    0xCC6 <= c :
    0xCCA <= c :
    c <= 0xCDE ?
    c <= 0xCD6 ?
    0xCD5 <= c :
    0xCDE <= c :
    0xCE0 <= c :
    c <= 0xD10 ?
    c <= 0xD03 ?
    c <= 0xCEF ?
    0xCE6 <= c :
    0xD02 <= c :
    c <= 0xD0C ?
    0xD05 <= c :
    0xD0E <= c :
    c <= 0xD39 ?
    c <= 0xD28 ?
    0xD12 <= c :
    0xD2A <= c :
    0xD3E <= c :
    c <= 0xD96 ?
    c <= 0xD61 ?
    c <= 0xD4D ?
    c <= 0xD48 ?
    0xD46 <= c :
    0xD4A <= c :
    c <= 0xD57 ?
    0xD57 <= c :
    0xD60 <= c :
    c <= 0xD83 ?
    c <= 0xD6F ?
    0xD66 <= c :
    0xD82 <= c :
    0xD85 <= c :
    c <= 0xDC6 ?
    c <= 0xDBB ?
    c <= 0xDB1 ?
    0xD9A <= c :
    0xDB3 <= c :
    c <= 0xDBD ?
    0xDBD <= c :
    0xDC0 <= c :
    c <= 0xDD4 ?
    c <= 0xDCA ?
    0xDCA <= c :
    0xDCF <= c :
    0xDD6 <= c :
    c <= 0xF39 ?
    c <= 0xEA7 ?
    c <= 0xE88 ?
    c <= 0xE4E ?
    c <= 0xDF3 ?
    c <= 0xDDF ?
    0xDD8 <= c :
    0xDF2 <= c :
    c <= 0xE3A ?
    0xE01 <= c :
    0xE40 <= c :
    c <= 0xE82 ?
    c <= 0xE59 ?
    0xE50 <= c :
    0xE81 <= c :
    c <= 0xE84 ?
    0xE84 <= c :
    0xE87 <= c :
    c <= 0xE9F ?
    c <= 0xE8D ?
    c <= 0xE8A ?
    0xE8A <= c :
    0xE8D <= c :
    c <= 0xE97 ?
    0xE94 <= c :
    0xE99 <= c :
    c <= 0xEA5 ?
    c <= 0xEA3 ?
    0xEA1 <= c :
    0xEA5 <= c :
    0xEA7 <= c :
    c <= 0xED9 ?
    c <= 0xEC4 ?
    c <= 0xEB9 ?
    c <= 0xEAB ?
    0xEAA <= c :
    0xEAD <= c :
    c <= 0xEBD ?
    0xEBB <= c :
    0xEC0 <= c :
    c <= 0xECD ?
    c <= 0xEC6 ?
    0xEC6 <= c :
    0xEC8 <= c :
    0xED0 <= c :
    c <= 0xF29 ?
    c <= 0xF00 ?
    c <= 0xEDD ?
    0xEDC <= c :
    0xF00 <= c :
    c <= 0xF19 ?
    0xF18 <= c :
    0xF20 <= c :
    c <= 0xF37 ?
    c <= 0xF35 ?
    0xF35 <= c :
    0xF37 <= c :
    0xF39 <= c :
    c <= 0x1059 ?
    c <= 0xFC6 ?
    c <= 0xF8B ?
    c <= 0xF6A ?
    c <= 0xF47 ?
    0xF3E <= c :
    0xF49 <= c :
    c <= 0xF84 ?
    0xF71 <= c :
    0xF86 <= c :
    c <= 0xFBC ?
    c <= 0xF97 ?
    0xF90 <= c :
    0xF99 <= c :
    0xFC6 <= c :
    c <= 0x1032 ?
    c <= 0x1027 ?
    c <= 0x1021 ?
    0x1000 <= c :
    0x1023 <= c :
    c <= 0x102A ?
    0x1029 <= c :
    0x102C <= c :
    c <= 0x1049 ?
    c <= 0x1039 ?
    0x1036 <= c :
    0x1040 <= c :
    0x1050 <= c :
    c <= 0x1248 ?
    c <= 0x1159 ?
    c <= 0x10FA ?
    c <= 0x10C5 ?
    0x10A0 <= c :
    0x10D0 <= c :
    c <= 0x10FC ?
    0x10FC <= c :
    0x1100 <= c :
    c <= 0x11F9 ?
    c <= 0x11A2 ?
    0x115F <= c :
    0x11A8 <= c :
    0x1200 <= c :
    c <= 0x125D ?
    c <= 0x1256 ?
    c <= 0x124D ?
    0x124A <= c :
    0x1250 <= c :
    c <= 0x1258 ?
    0x1258 <= c :
    0x125A <= c :
    c <= 0x128D ?
    c <= 0x1288 ?
    0x1260 <= c :
    0x128A <= c :
    0x1290 <= c :
    c <= 0x30FF ?
    c <= 0x1FB4 ?
    c <= 0x180D ?
    c <= 0x16EA ?
    c <= 0x135A ?
    c <= 0x12C5 ?
    c <= 0x12BE ?
    c <= 0x12B5 ?
    0x12B2 <= c :
    0x12B8 <= c :
    c <= 0x12C0 ?
    0x12C0 <= c :
    0x12C2 <= c :
    c <= 0x1310 ?
    c <= 0x12D6 ?
    0x12C8 <= c :
    0x12D8 <= c :
    c <= 0x1315 ?
    0x1312 <= c :
    0x1318 <= c :
    c <= 0x166C ?
    c <= 0x138F ?
    c <= 0x135F ?
    0x135F <= c :
    0x1380 <= c :
    c <= 0x13F4 ?
    0x13A0 <= c :
    0x1401 <= c :
    c <= 0x169A ?
    c <= 0x1676 ?
    0x166F <= c :
    0x1681 <= c :
    0x16A0 <= c :
    c <= 0x1770 ?
    c <= 0x1734 ?
    c <= 0x170C ?
    c <= 0x16F0 ?
    0x16EE <= c :
    0x1700 <= c :
    c <= 0x1714 ?
    0x170E <= c :
    0x1720 <= c :
    c <= 0x176C ?
    c <= 0x1753 ?
    0x1740 <= c :
    0x1760 <= c :
    0x176E <= c :
    c <= 0x17D7 ?
    c <= 0x17B3 ?
    c <= 0x1773 ?
    0x1772 <= c :
    0x1780 <= c :
    c <= 0x17D3 ?
    0x17B6 <= c :
    0x17D7 <= c :
    c <= 0x17E9 ?
    c <= 0x17DD ?
    0x17DC <= c :
    0x17E0 <= c :
    0x180B <= c :
    c <= 0x1B59 ?
    c <= 0x196D ?
    c <= 0x191C ?
    c <= 0x1877 ?
    c <= 0x1819 ?
    0x1810 <= c :
    0x1820 <= c :
    c <= 0x18A9 ?
    0x1880 <= c :
    0x1900 <= c :
    c <= 0x193B ?
    c <= 0x192B ?
    0x1920 <= c :
    0x1930 <= c :
    0x1946 <= c :
    c <= 0x19D9 ?
    c <= 0x19A9 ?
    c <= 0x1974 ?
    0x1970 <= c :
    0x1980 <= c :
    c <= 0x19C9 ?
    0x19B0 <= c :
    0x19D0 <= c :
    c <= 0x1B4B ?
    c <= 0x1A1B ?
    0x1A00 <= c :
    0x1B00 <= c :
    0x1B50 <= c :
    c <= 0x1F45 ?
    c <= 0x1EF9 ?
    c <= 0x1DCA ?
    c <= 0x1B73 ?
    0x1B6B <= c :
    0x1D00 <= c :
    c <= 0x1E9B ?
    0x1DFE <= c :
    0x1EA0 <= c :
    c <= 0x1F1D ?
    c <= 0x1F15 ?
    0x1F00 <= c :
    0x1F18 <= c :
    0x1F20 <= c :
    c <= 0x1F5B ?
    c <= 0x1F57 ?
    c <= 0x1F4D ?
    0x1F48 <= c :
    0x1F50 <= c :
    c <= 0x1F59 ?
    0x1F59 <= c :
    0x1F5B <= c :
    c <= 0x1F7D ?
    c <= 0x1F5D ?
    0x1F5D <= c :
    0x1F5F <= c :
    0x1F80 <= c :
    c <= 0x2149 ?
    c <= 0x20DC ?
    c <= 0x1FF4 ?
    c <= 0x1FCC ?
    c <= 0x1FBE ?
    c <= 0x1FBC ?
    0x1FB6 <= c :
    0x1FBE <= c :
    c <= 0x1FC4 ?
    0x1FC2 <= c :
    0x1FC6 <= c :
    c <= 0x1FDB ?
    c <= 0x1FD3 ?
    0x1FD0 <= c :
    0x1FD6 <= c :
    c <= 0x1FEC ?
    0x1FE0 <= c :
    0x1FF2 <= c :
    c <= 0x2071 ?
    c <= 0x2040 ?
    c <= 0x1FFC ?
    0x1FF6 <= c :
    0x203F <= c :
    c <= 0x2054 ?
    0x2054 <= c :
    0x2071 <= c :
    c <= 0x2094 ?
    c <= 0x207F ?
    0x207F <= c :
    0x2090 <= c :
    0x20D0 <= c :
    c <= 0x211D ?
    c <= 0x2107 ?
    c <= 0x20EF ?
    c <= 0x20E1 ?
    0x20E1 <= c :
    0x20E5 <= c :
    c <= 0x2102 ?
    0x2102 <= c :
    0x2107 <= c :
    c <= 0x2115 ?
    c <= 0x2113 ?
    0x210A <= c :
    0x2115 <= c :
    0x2119 <= c :
    c <= 0x212D ?
    c <= 0x2126 ?
    c <= 0x2124 ?
    0x2124 <= c :
    0x2126 <= c :
    c <= 0x2128 ?
    0x2128 <= c :
    0x212A <= c :
    c <= 0x213F ?
    c <= 0x2139 ?
    0x212F <= c :
    0x213C <= c :
    0x2145 <= c :
    c <= 0x2DB6 ?
    c <= 0x2CE4 ?
    c <= 0x2C5E ?
    c <= 0x2184 ?
    c <= 0x214E ?
    0x214E <= c :
    0x2160 <= c :
    c <= 0x2C2E ?
    0x2C00 <= c :
    0x2C30 <= c :
    c <= 0x2C77 ?
    c <= 0x2C6C ?
    0x2C60 <= c :
    0x2C74 <= c :
    0x2C80 <= c :
    c <= 0x2D96 ?
    c <= 0x2D65 ?
    c <= 0x2D25 ?
    0x2D00 <= c :
    0x2D30 <= c :
    c <= 0x2D6F ?
    0x2D6F <= c :
    0x2D80 <= c :
    c <= 0x2DAE ?
    c <= 0x2DA6 ?
    0x2DA0 <= c :
    0x2DA8 <= c :
    0x2DB0 <= c :
    c <= 0x302F ?
    c <= 0x2DD6 ?
    c <= 0x2DC6 ?
    c <= 0x2DBE ?
    0x2DB8 <= c :
    0x2DC0 <= c :
    c <= 0x2DCE ?
    0x2DC8 <= c :
    0x2DD0 <= c :
    c <= 0x3007 ?
    c <= 0x2DDE ?
    0x2DD8 <= c :
    0x3005 <= c :
    0x3021 <= c :
    c <= 0x309A ?
    c <= 0x303C ?
    c <= 0x3035 ?
    0x3031 <= c :
    0x3038 <= c :
    c <= 0x3096 ?
    0x3041 <= c :
    0x3099 <= c :
    c <= 0x30FA ?
    c <= 0x309F ?
    0x309D <= c :
    0x30A1 <= c :
    0x30FC <= c :
    c <= 0x1049D ?
    c <= 0xFE23 ?
    c <= 0xFB06 ?
    c <= 0xA71A ?
    c <= 0x31FF ?
    c <= 0x318E ?
    c <= 0x312C ?
    0x3105 <= c :
    0x3131 <= c :
    c <= 0x31B7 ?
    0x31A0 <= c :
    0x31F0 <= c :
    c <= 0x9FBB ?
    c <= 0x4DB5 ?
    0x3400 <= c :
    0x4E00 <= c :
    c <= 0xA48C ?
    0xA000 <= c :
    0xA717 <= c :
    c <= 0xFA2D ?
    c <= 0xA873 ?
    c <= 0xA827 ?
    0xA800 <= c :
    0xA840 <= c :
    c <= 0xD7A3 ?
    0xAC00 <= c :
    0xF900 <= c :
    c <= 0xFAD9 ?
    c <= 0xFA6A ?
    0xFA30 <= c :
    0xFA70 <= c :
    0xFB00 <= c :
    c <= 0xFB44 ?
    c <= 0xFB3C ?
    c <= 0xFB28 ?
    c <= 0xFB17 ?
    0xFB13 <= c :
    0xFB1D <= c :
    c <= 0xFB36 ?
    0xFB2A <= c :
    0xFB38 <= c :
    c <= 0xFB41 ?
    c <= 0xFB3E ?
    0xFB3E <= c :
    0xFB40 <= c :
    0xFB43 <= c :
    c <= 0xFDC7 ?
    c <= 0xFD3D ?
    c <= 0xFBB1 ?
    0xFB46 <= c :
    0xFBD3 <= c :
    c <= 0xFD8F ?
    0xFD50 <= c :
    0xFD92 <= c :
    c <= 0xFE0F ?
    c <= 0xFDFB ?
    0xFDF0 <= c :
    0xFE00 <= c :
    0xFE20 <= c :
    c <= 0x1000B ?
    c <= 0xFF3F ?
    c <= 0xFEFC ?
    c <= 0xFE4F ?
    c <= 0xFE34 ?
    0xFE33 <= c :
    0xFE4D <= c :
    c <= 0xFE74 ?
    0xFE70 <= c :
    0xFE76 <= c :
    c <= 0xFF3A ?
    c <= 0xFF19 ?
    0xFF10 <= c :
    0xFF21 <= c :
    0xFF3F <= c :
    c <= 0xFFCF ?
    c <= 0xFFBE ?
    c <= 0xFF5A ?
    0xFF41 <= c :
    0xFF66 <= c :
    c <= 0xFFC7 ?
    0xFFC2 <= c :
    0xFFCA <= c :
    c <= 0xFFDC ?
    c <= 0xFFD7 ?
    0xFFD2 <= c :
    0xFFDA <= c :
    0x10000 <= c :
    c <= 0x10174 ?
    c <= 0x1004D ?
    c <= 0x1003A ?
    c <= 0x10026 ?
    0x1000D <= c :
    0x10028 <= c :
    c <= 0x1003D ?
    0x1003C <= c :
    0x1003F <= c :
    c <= 0x100FA ?
    c <= 0x1005D ?
    0x10050 <= c :
    0x10080 <= c :
    0x10140 <= c :
    c <= 0x103C3 ?
    c <= 0x1034A ?
    c <= 0x1031E ?
    0x10300 <= c :
    0x10330 <= c :
    c <= 0x1039D ?
    0x10380 <= c :
    0x103A0 <= c :
    c <= 0x103D5 ?
    c <= 0x103CF ?
    0x103C8 <= c :
    0x103D1 <= c :
    0x10400 <= c :
    c <= 0x1D4AC ?
    c <= 0x10A3F ?
    c <= 0x10915 ?
    c <= 0x10835 ?
    c <= 0x10805 ?
    c <= 0x104A9 ?
    0x104A0 <= c :
    0x10800 <= c :
    c <= 0x10808 ?
    0x10808 <= c :
    0x1080A <= c :
    c <= 0x1083C ?
    c <= 0x10838 ?
    0x10837 <= c :
    0x1083C <= c :
    c <= 0x1083F ?
    0x1083F <= c :
    0x10900 <= c :
    c <= 0x10A17 ?
    c <= 0x10A06 ?
    c <= 0x10A03 ?
    0x10A00 <= c :
    0x10A05 <= c :
    c <= 0x10A13 ?
    0x10A0C <= c :
    0x10A15 <= c :
    c <= 0x10A3A ?
    c <= 0x10A33 ?
    0x10A19 <= c :
    0x10A38 <= c :
    0x10A3F <= c :
    c <= 0x1D1AD ?
    c <= 0x1D172 ?
    c <= 0x12462 ?
    c <= 0x1236E ?
    0x12000 <= c :
    0x12400 <= c :
    c <= 0x1D169 ?
    0x1D165 <= c :
    0x1D16D <= c :
    c <= 0x1D18B ?
    c <= 0x1D182 ?
    0x1D17B <= c :
    0x1D185 <= c :
    0x1D1AA <= c :
    c <= 0x1D49F ?
    c <= 0x1D454 ?
    c <= 0x1D244 ?
    0x1D242 <= c :
    0x1D400 <= c :
    c <= 0x1D49C ?
    0x1D456 <= c :
    0x1D49E <= c :
    c <= 0x1D4A6 ?
    c <= 0x1D4A2 ?
    0x1D4A2 <= c :
    0x1D4A5 <= c :
    0x1D4A9 <= c :
    c <= 0x1D6C0 ?
    c <= 0x1D51C ?
    c <= 0x1D505 ?
    c <= 0x1D4BB ?
    c <= 0x1D4B9 ?
    0x1D4AE <= c :
    0x1D4BB <= c :
    c <= 0x1D4C3 ?
    0x1D4BD <= c :
    0x1D4C5 <= c :
    c <= 0x1D514 ?
    c <= 0x1D50A ?
    0x1D507 <= c :
    0x1D50D <= c :
    0x1D516 <= c :
    c <= 0x1D546 ?
    c <= 0x1D53E ?
    c <= 0x1D539 ?
    0x1D51E <= c :
    0x1D53B <= c :
    c <= 0x1D544 ?
    0x1D540 <= c :
    0x1D546 <= c :
    c <= 0x1D6A5 ?
    c <= 0x1D550 ?
    0x1D54A <= c :
    0x1D552 <= c :
    0x1D6A8 <= c :
    c <= 0x1D788 ?
    c <= 0x1D734 ?
    c <= 0x1D6FA ?
    c <= 0x1D6DA ?
    0x1D6C2 <= c :
    0x1D6DC <= c :
    c <= 0x1D714 ?
    0x1D6FC <= c :
    0x1D716 <= c :
    c <= 0x1D76E ?
    c <= 0x1D74E ?
    0x1D736 <= c :
    0x1D750 <= c :
    0x1D770 <= c :
    c <= 0x1D7FF ?
    c <= 0x1D7C2 ?
    c <= 0x1D7A8 ?
    0x1D78A <= c :
    0x1D7AA <= c :
    c <= 0x1D7CB ?
    0x1D7C4 <= c :
    0x1D7CE <= c :
    c <= 0x2FA1D ?
    c <= 0x2A6D6 ?
    0x20000 <= c :
    0x2F800 <= c :
    0xE0100 <= c && c <= 0xE01EF;
    // #/generated#
}

            return {
                isDigit: isDigit, isIdentifierStart: isIdentifierStart, isHexDigit: isHexDigit, isAlpha: isAlpha, isSpace: isSpace, isLineTerminator: isLineTerminator, isFormatChar: isFormatChar, isIdentifierPart: isIdentifierPart
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.isDigit = isDigit;
    this.Concurrent.Thread.Compiler.isIdentifierStart = isIdentifierStart;
    this.Concurrent.Thread.Compiler.isHexDigit = isHexDigit;
    this.Concurrent.Thread.Compiler.isAlpha = isAlpha;
    this.Concurrent.Thread.Compiler.isSpace = isSpace;
    this.Concurrent.Thread.Compiler.isLineTerminator = isLineTerminator;
    this.Concurrent.Thread.Compiler.isFormatChar = isFormatChar;
    this.Concurrent.Thread.Compiler.isIdentifierPart = isIdentifierPart;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Http || (typeof this.Concurrent.Thread.Http != 'object' && typeof this.Concurrent.Thread.Http != 'function') ) this.Concurrent.Thread.Http = new Object();
    if ( this.Concurrent.Thread.Http.send === undefined ) this.Concurrent.Thread.Http.send = undefined;
    if ( this.Concurrent.Thread.Http.get === undefined ) this.Concurrent.Thread.Http.get = undefined;
    if ( this.Concurrent.Thread.Http.post === undefined ) this.Concurrent.Thread.Http.post = undefined;
with ( function(){
with ( Concurrent.Thread.Http ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Http';

var createXMLHttpRequest;  // Set up according to environment.
try {
    new XMLHttpRequest();
    createXMLHttpRequest = function ( ) {
        return new XMLHttpRequest();
    };
} catch ( e ) {
    try {
        // MSXML3 or later
        new ActiveXObject("Msxml2.XMLHTTP");
        createXMLHttpRequest = function ( ) {
            return new ActiveXObject("Msxml2.XMLHTTP");
        };
    } catch ( e ) {
        try {
            // MSXML up to 2
            new ActiveXObject("Microsoft.XMLHTTP");
            createXMLHttpRequest = function ( ) {
                return new ActiveXObject("Microsoft.XMLHTTP");
            };
        } catch ( e ) {
            throw new Error(NAMESPACE + ": can't load XMLHttpRequest object");
        }
    }
}

function send ( method, url, body, headers ) {
    throw new Error(NAMESPACE + ".send is unusable in non-compiled function");
}

var LoadedException = {};

send.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    var method=$args[0], url=$args[1], body=$args[2], headers=$args[3];
    if ( !headers || !(headers instanceof Array) ) headers = [];
    var req = createXMLHttpRequest();
    req.open(method, url, true);
    for ( var i=0;  i < headers.length;  i+=2 ) {
        req.setRequestHeader(headers[i], headers[i+1]);
    }
    var self = Concurrent.Thread.self();
    var loaded    = false;
    var cache_hit = true;
    req.onreadystatechange = function ( ) {
        if ( req.readyState == 4 ) {
            loaded = true;
            if ( !cache_hit ) self.notify(LoadedException);
        }
    };
    req.send(body);  // Firefox occasionally causes "onload" event here. Maybe, it occurs in case of cache-hit.
    cache_hit = false;
    if ( loaded ) {
        return {
            continuation: $cont,
            ret_val     : req,
            timeout     : undefined
        };
    } else {
        var ex_handler = {
            procedure: function ( e ) {
                if ( e === LoadedException ) {
                    return {
                        continuation: $cont,
                        ret_val     : req,
                        timeout     : undefined
                    };
                } else {
                    try{ req.abort(); }catch(_){}  // IE less than 7 does not support "abort".
                    return {
                        continuation: $cont.exception,
                        ret_val     : e,
                        timeout     : undefined
                    };
                }
            },
            this_val : null
        };
        ex_handler.exception = ex_handler;  // Cyclic reference assures to abort request.
        return {
            timeout     : -1,
            continuation: {
                procedure: null,
                this_val : null,
                exception: ex_handler
            }
        };
    }
};

function get ( url, headers ) {
    throw new Error(NAMESPACE + ".get is unusable in non-compiled function");
}

get.$Concurrent_Thread_compiled = function ($this, $args, $cont) {
    return send.$Concurrent_Thread_compiled(
        null,
        ["GET", $args[0], $args[1], null],
        $cont
    );
}

function post ( url, body, headers ) {
    throw new Error(NAMESPACE + ".post is unusable in non-compiled function");
}

post.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    var url=$args[0], body=$args[1], headers=$args[2];
    if ( typeof body == "object" ) {
        var vals = [];
        for ( var i in body ) {
            if ( body.hasOwnProperty(i) ) {
                vals.push( encodeURIComponent(i) + "=" + encodeURIComponent(body[i]) );
            }
        }
        body = vals.join("&");
    }
    if ( !headers || !(headers instanceof Array) ) headers = [];
    var content_type_exists = false;
    for ( var i=0;  i < headers.length;  i+=2 ) {
        if ( String(headers[i]).match(/^Content-type$/i) ) {
            content_type_exists = true;
            break;
        }
    }
    if ( !content_type_exists ) {
        headers = headers.concat("Content-type", "application/x-www-form-urlencoded");
    }
    return send.$Concurrent_Thread_compiled(
        null,
        ["POST", url, body, headers],
        $cont
    );
};

            return {
                send: send, post: post, get: get
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Http.send = send;
    this.Concurrent.Thread.Http.post = post;
    this.Concurrent.Thread.Http.get = get;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( this.Concurrent.Thread.Mutex === undefined ) this.Concurrent.Thread.Mutex = undefined;
with ( function(){
with ( Data ) {
with ( Data.Error ) {
with ( Concurrent ) {
with ( Concurrent.Thread ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread';

function Mutex ( ) {
    this._acquiring = null;
    this._waiting   = new LinkedList();
}

var proto = Mutex.prototype;

proto.isAcquirable = function ( ) {
    return !this._acquiring  &&  this._waiting.isEmpty();
};

proto.acquire = function ( ) {
    throw new Error("can't `acquire' in non-converted function");
};

proto.acquire.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
    if ( $this.isAcquirable() ) {
        $this._acquiring = Thread.self();
        return {
            continuation: $cont ,
            ret_val     : void 0,
            timeout     : void 0
        };
    } else {
        $this._waiting.push(Thread.self());
        var callee = arguments.callee;
        return {
            continuation: {
                procedure: null,
                this_val : null,
                exception: {
                    procedure: function( e ){
                        if ( e === releasedException ) {
                            if ( $this._waiting.shift() !== Thread.self() ) {
                                return {
                                    continuation: $cont.exception,
                                    ret_val     : new IllegalStateError("unknown state (maybe bug)"),
                                    timeout     : void 0
                                };
                            }
                            $this._acquiring = Thread.self();
                            return {
                                continuation: $cont,
                                ret_val     : void 0,
                                timeout     : void 0
                            };
                        } else {
                            $this._waiting.head().find(function( it ){
                                return it === Thread.self();
                            }).remove();
                            return {
                                continuation: $cont.exception,
                                ret_val     : e,
                                timeout     : void 0
                            };
                        }
                    },
                    this_val : null,
                    exception: $cont.exception
                }
            },
            ret_val: void 0,
            timeout: -1
        };
    }
};

proto.release = function ( ) {
    if ( !this._acquiring ) {
        throw new IllegalStateError("mutex is not locked");
    }
    if ( this._acquiring !== Thread.self() ) {
        throw new IllegalStateError("mutex can be released only by the thread locking it");
    }
    this._acquiring = null;
    if ( !this._waiting.isEmpty() ) {
        this._waiting.head().value().notify(releasedException);
    }
};

var releasedException = {};

            return {
                Mutex: Mutex
            };
        }();
    }
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.Mutex = Mutex;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.Expression === undefined ) this.Concurrent.Thread.Compiler.Expression = undefined;
    if ( this.Concurrent.Thread.Compiler.UnaryExpression === undefined ) this.Concurrent.Thread.Compiler.UnaryExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BinaryExpression === undefined ) this.Concurrent.Thread.Compiler.BinaryExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.ThisExpression === undefined ) this.Concurrent.Thread.Compiler.ThisExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.Identifier === undefined ) this.Concurrent.Thread.Compiler.Identifier = undefined;
    if ( this.Concurrent.Thread.Compiler.Literal === undefined ) this.Concurrent.Thread.Compiler.Literal = undefined;
    if ( this.Concurrent.Thread.Compiler.NumberLiteral === undefined ) this.Concurrent.Thread.Compiler.NumberLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.StringLiteral === undefined ) this.Concurrent.Thread.Compiler.StringLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.RegExpLiteral === undefined ) this.Concurrent.Thread.Compiler.RegExpLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.NullLiteral === undefined ) this.Concurrent.Thread.Compiler.NullLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.BooleanLiteral === undefined ) this.Concurrent.Thread.Compiler.BooleanLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.TrueLiteral === undefined ) this.Concurrent.Thread.Compiler.TrueLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.FalseLiteral === undefined ) this.Concurrent.Thread.Compiler.FalseLiteral = undefined;
    if ( this.Concurrent.Thread.Compiler.ArrayInitializer === undefined ) this.Concurrent.Thread.Compiler.ArrayInitializer = undefined;
    if ( this.Concurrent.Thread.Compiler.Elision === undefined ) this.Concurrent.Thread.Compiler.Elision = undefined;
    if ( this.Concurrent.Thread.Compiler.ObjectInitializer === undefined ) this.Concurrent.Thread.Compiler.ObjectInitializer = undefined;
    if ( this.Concurrent.Thread.Compiler.FunctionExpression === undefined ) this.Concurrent.Thread.Compiler.FunctionExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.DotAccessor === undefined ) this.Concurrent.Thread.Compiler.DotAccessor = undefined;
    if ( this.Concurrent.Thread.Compiler.BracketAccessor === undefined ) this.Concurrent.Thread.Compiler.BracketAccessor = undefined;
    if ( this.Concurrent.Thread.Compiler.NewExpression === undefined ) this.Concurrent.Thread.Compiler.NewExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.CallExpression === undefined ) this.Concurrent.Thread.Compiler.CallExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.PostIncExpression === undefined ) this.Concurrent.Thread.Compiler.PostIncExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.PostDecExpression === undefined ) this.Concurrent.Thread.Compiler.PostDecExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.PreIncExpression === undefined ) this.Concurrent.Thread.Compiler.PreIncExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.PreDecExpression === undefined ) this.Concurrent.Thread.Compiler.PreDecExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.DeleteExpression === undefined ) this.Concurrent.Thread.Compiler.DeleteExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.VoidExpression === undefined ) this.Concurrent.Thread.Compiler.VoidExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.TypeofExpression === undefined ) this.Concurrent.Thread.Compiler.TypeofExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.PosExpression === undefined ) this.Concurrent.Thread.Compiler.PosExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.NegExpression === undefined ) this.Concurrent.Thread.Compiler.NegExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitNotExpression === undefined ) this.Concurrent.Thread.Compiler.BitNotExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.NotExpression === undefined ) this.Concurrent.Thread.Compiler.NotExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.MulExpression === undefined ) this.Concurrent.Thread.Compiler.MulExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.DivExpression === undefined ) this.Concurrent.Thread.Compiler.DivExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.ModExpression === undefined ) this.Concurrent.Thread.Compiler.ModExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.AddExpression === undefined ) this.Concurrent.Thread.Compiler.AddExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.SubExpression === undefined ) this.Concurrent.Thread.Compiler.SubExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.LShiftExpression === undefined ) this.Concurrent.Thread.Compiler.LShiftExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.RShiftExpression === undefined ) this.Concurrent.Thread.Compiler.RShiftExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.URShiftExpression === undefined ) this.Concurrent.Thread.Compiler.URShiftExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.LessThanExpression === undefined ) this.Concurrent.Thread.Compiler.LessThanExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.GreaterThanExpression === undefined ) this.Concurrent.Thread.Compiler.GreaterThanExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.LessEqualExpression === undefined ) this.Concurrent.Thread.Compiler.LessEqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.GreaterEqualExpression === undefined ) this.Concurrent.Thread.Compiler.GreaterEqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.InstanceofExpression === undefined ) this.Concurrent.Thread.Compiler.InstanceofExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.InExpression === undefined ) this.Concurrent.Thread.Compiler.InExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.EqualExpression === undefined ) this.Concurrent.Thread.Compiler.EqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.NotEqualExpression === undefined ) this.Concurrent.Thread.Compiler.NotEqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.StrictEqualExpression === undefined ) this.Concurrent.Thread.Compiler.StrictEqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.StrictNotEqualExpression === undefined ) this.Concurrent.Thread.Compiler.StrictNotEqualExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitAndExpression === undefined ) this.Concurrent.Thread.Compiler.BitAndExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitXorExpression === undefined ) this.Concurrent.Thread.Compiler.BitXorExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitOrExpression === undefined ) this.Concurrent.Thread.Compiler.BitOrExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.AndExpression === undefined ) this.Concurrent.Thread.Compiler.AndExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.OrExpression === undefined ) this.Concurrent.Thread.Compiler.OrExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.ConditionalExpression === undefined ) this.Concurrent.Thread.Compiler.ConditionalExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.AssignExpression === undefined ) this.Concurrent.Thread.Compiler.AssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.SimpleAssignExpression === undefined ) this.Concurrent.Thread.Compiler.SimpleAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.MulAssignExpression === undefined ) this.Concurrent.Thread.Compiler.MulAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.DivAssignExpression === undefined ) this.Concurrent.Thread.Compiler.DivAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.ModAssignExpression === undefined ) this.Concurrent.Thread.Compiler.ModAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.AddAssignExpression === undefined ) this.Concurrent.Thread.Compiler.AddAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.SubAssignExpression === undefined ) this.Concurrent.Thread.Compiler.SubAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.LShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.LShiftAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.RShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.RShiftAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.URShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.URShiftAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitAndAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitAndAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitXorAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitXorAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.BitOrAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitOrAssignExpression = undefined;
    if ( this.Concurrent.Thread.Compiler.CommaExpression === undefined ) this.Concurrent.Thread.Compiler.CommaExpression = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

function Expression ( ) {
    // This is kind of abstract class.
}

var proto = Expression.prototype;

proto.toString = function ( ) {
    Kit.codeBug("Unimplemented method `toString' of class: " + this.constructor);
};

proto.containsFunctionCall = function ( ) {
    Kit.codeBug("Unimplemented method `containsFunctionCall' of class: " + this.constructor);
};

proto.hasSideEffect = function ( ) {
    Kit.codeBug("Unimplemented method `hasSideEffect' of class: " + this.constructor);
};

proto.hasLvalue = function ( ) {
    return false;
};

function UnaryExpression ( e ) {
    // This is kind of abstract class and should not be instantiated directly.
    // It just provides default implementations of methods and constructor.
    this.exp = e;  // Expression
}

var proto = UnaryExpression.prototype = new Expression();
proto.constructor = UnaryExpression;

proto.containsFunctionCall = function ( ) {
    return this.exp.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
    return this.exp.hasSideEffect();
};

function BinaryExpression ( l, r ) {
    // This is kind of abstract class and should not be instantiated directly.
    // It just provides default implementations of methods and constructor.
    this.left  = l;  // Expression
    this.right = r;  // Expression
}

var proto = BinaryExpression.prototype = new Expression();
proto.constructor = BinaryExpression;

proto.containsFunctionCall = function ( ) {
    return this.left.containsFunctionCall() || this.right.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
    return this.left.hasSideEfect() || this.right.hasSideEffect();
};

function ThisExpression ( ) {
    return THIS_EXPRESSION;  // Reuse object.
}

var proto = ThisExpression.prototype = new Expression();
proto.constructor = ThisExpression;

proto.toString = function ( ) {
    return "this";
};

proto.containsFunctionCall = function ( ) {
    return false;
};

proto.hasSideEffect = function ( ) {
    return false;
};

function temp ( ) { }
temp.prototype = ThisExpression.prototype;
var THIS_EXPRESSION = new temp();

function Identifier ( s ) {
    this.string = String(s);
    this.value  = eval('"' + this.string + '"');
}

var proto = Identifier.prototype = new Expression();
proto.constructor = Identifier;

proto.toString = function ( ) {
    return this.string;
};

proto.valueOf = function ( ) {
    return this.value;
};

proto.hasLvalue = function ( ) {
    return true;
};

proto.containsFunctionCall = function ( ) {
    return false;
};

proto.hasSideEffect = function ( ) {
    return false;
};

function Literal ( s ) {
    this.string = String(s);
    this.value  = eval(this.string);
}

var proto = Literal.prototype = new Expression();
proto.constructor = Literal;

proto.toString = function ( ) {
    return this.string;
};

proto.valueOf = function ( ) {
    return this.value;
};

proto.containsFunctionCall = function ( ) {
    return false;
};

proto.hasSideEffect = function ( ) {
    return false;
};

function NumberLiteral ( s ) {
    Literal.apply(this, arguments);
}

var proto = NumberLiteral.prototype = new Literal();
proto.constructor = NumberLiteral;

function StringLiteral ( s ) {
    Literal.apply(this, arguments);
}

var proto = StringLiteral.prototype = new Literal();
proto.constructor = StringLiteral;

function RegExpLiteral ( s ) {
    Literal.apply(this, arguments);
}

var proto = RegExpLiteral.prototype = new Literal();
proto.constructor = RegExpLiteral;

function NullLiteral ( ) {
    return NULL_LITERAL;  // Reuse object.
}

var proto = NullLiteral.prototype = new Literal();
proto.constructor = NullLiteral;

proto.string = "null";
proto.vakue  = null;

proto.toString = function ( ) {
    return "null";
};

proto.valueOf = function ( ) {
    return null;
};

function temp ( ) { }
temp.prototype = NullLiteral.prototype;
var NULL_LITERAL = new temp();

function BooleanLiteral ( ) { }

var proto = BooleanLiteral.prototype = new Literal();
proto.constructor = BooleanLiteral;

function TrueLiteral ( ) {
    return TRUE_LITERAL;  // Reuse object.
}

var proto = TrueLiteral.prototype = new BooleanLiteral();
proto.constructor = TrueLiteral;

proto.string = "true";
proto.vakue  = true;

proto.toString = function ( ) {
    return "true";
};

proto.valueOf = function ( ) {
    return true;
};

function temp ( ) { }
temp.prototype = TrueLiteral.prototype;
var TRUE_LITERAL = new temp();

function FalseLiteral ( ) {
    return FALSE_LITERAL;  // Reuse object.
}

var proto = FalseLiteral.prototype = new BooleanLiteral();
proto.constructor = FalseLiteral;

proto.string = "false";
proto.vakue  = false;

proto.toString = function ( ) {
    return "false";
};

proto.valueOf = function ( ) {
    return false;
};

function temp ( ) { }
temp.prototype = FalseLiteral.prototype;
var FALSE_LITERAL = new temp();

function ArrayInitializer ( elems ) {
    this.elems = elems;  // array of Expression
}

var proto = ArrayInitializer.prototype = new Expression();
proto.constructor = ArrayInitializer;

proto.toString = function ( ) {
    return "[" + this.elems.join(", ") + "]";
};

proto.containsFunctionCall = function ( ) {
    for ( var i=0;  i < this.elems.length;  i++ ) {
        if ( this.elems[i].containsFunctionCall() ) return true;
    }
    return false;
};

proto.hasSideEfect = function ( ) {
    for ( var i=0;  i < this.elems.length;  i++ ) {
        if ( this.elems[i].hasSideEffect() ) return true;
    }
    return false;
};

function Elision ( ) { }

var proto = Elision.prototype = new Expression();
proto.constructor = Elision;

proto.toString = function ( ) {
    return "";
};

proto.containsFunctionCall = function ( ) {
    return false;
};

proto.hasSideEffect = function ( ) {
    return false;
};

function ObjectInitializer ( v ) {
    this.pairs = v;  // array of {prop: Identifier or Literal,  exp: Expression}
}

var proto = ObjectInitializer.prototype = new Expression();
proto.constructor = ObjectInitializer;

proto.toString = function ( ) {
    var buf = [];
    for ( var i=0;  i < this.pairs.length;  i++ ) {
        buf.push( String(this.pairs[i].prop) + ":" + String(this.pairs[i].exp) );
    }
    return "{" + buf.join(", ") + "}";
};

proto.containsFunctionCall = function ( ) {
    for ( var i=0;  i < this.pairs.length;  i++ ) {
        if ( this.pairs[i].exp.containsFunctionCall() ) return true;
    }
    return false;
};

proto.hasSideEffect = function ( ) {
    for ( var i=0;  i < this.pairs.length;  i++ ) {
        if ( this.pairs[i].exp.hasSideEffect() ) return true;
    }
    return false;
};

function FunctionExpression ( name, params, body ) {
    this.name   = name;    // Identifier or null
    this.params = params;  // array of Identifier
    this.body   = body;    // cons-list of Statement
}

var proto = FunctionExpression.prototype = new Expression();
proto.constructor = FunctionExpression;

proto.toString = function ( ) {
    var buf = ["(function "];
    if ( this.name ) buf.push(this.name);
    buf.push( "(", this.params.join(", "), ") {\n");
    this.body.forEach(function( it ){
        buf.push(it, "\n");
    });
    buf.push("})");
    return buf.join("");
};

proto.containsFunctionCall = function ( ) {
    return false;
};

proto.hasSideEffect = function ( ) {
    return false;
};

function DotAccessor ( base, prop ) {
    this.base = base;  // Expression
    this.prop = prop;  // Identifier
}

var proto = DotAccessor.prototype = new Expression();
proto.constructor = DotAccessor;

proto.toString = function ( ) {
    return String(this.base) + "." + String(this.prop);
};

proto.hasLvalue = function ( ) {
    return true;
};

proto.containsFunctionCall = function ( ) {
    return this.base.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
    return this.base.hasSideEffect();
};

function BracketAccessor ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = BracketAccessor.prototype = new BinaryExpression();
proto.constructor = BracketAccessor;

proto.toString = function ( ) {
    return [ this.left, "[", this.right, "]" ].join("");
};

proto.hasLvalue = function ( ) {
    return true;
};

function NewExpression ( func, args ) {
    this.func = func;  // Expression
    this.args = args;  // array of Expression
}

var proto = NewExpression.prototype = new Expression();
proto.constructor = NewExpression;

proto.toString = function ( ) {
    return [ "new ", this.func, "(", this.args.join(", "), ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
    return true;
};

proto.hasSideEffect = function ( ) {
    return true;
};

function CallExpression ( func, args ) {
    this.func = func;  // Expression
    this.args = args;  // array of Expression
}

var proto = CallExpression.prototype = new Expression();
proto.constructor = CallExpression;

proto.toString = function ( ) {
    return [ this.func, "(", this.args.join(", "), ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
    return true;
};

proto.hasSideEffect = function ( ) {
    return true;
};

function PostIncExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = PostIncExpression.prototype = new UnaryExpression();
proto.constructor = PostIncExpression;

proto.toString = function ( ) {
    return String(this.exp) + "++";
};

proto.hasSideEffect = function ( ) {
    return true;
};

function PostDecExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = PostDecExpression.prototype = new UnaryExpression();
proto.constructor = PostDecExpression;

proto.toString = function ( ) {
    return String(this.exp) + "--";
};

proto.hasSideEffect = function ( ) {
    return true;
};

function PreIncExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = PreIncExpression.prototype = new UnaryExpression();
proto.constructor = PreIncExpression;

proto.toString = function ( ) {
    return "++" + String(this.exp);
};

proto.hasSideEffect = function ( ) {
    return true;
};

function PreDecExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = PreDecExpression.prototype = new UnaryExpression();
proto.constructor = PreDecExpression;

proto.toString = function ( ) {
    return "--" + String(this.exp);
};

proto.hasSideEffect = function ( ) {
    return true;
};

function DeleteExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = DeleteExpression.prototype = new UnaryExpression();
proto.constructor = DeleteExpression;

proto.toString = function ( ) {
    return "delete " + String(this.exp);
};

proto.hasSideEffect = function ( ) {
    return true;
};

function VoidExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = VoidExpression.prototype = new UnaryExpression();
proto.constructor = VoidExpression;

proto.toString = function ( ) {
    return "void " + String(this.exp);
};

function TypeofExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = TypeofExpression.prototype = new UnaryExpression();
proto.constructor = TypeofExpression;

proto.toString = function ( ) {
    return "typeof " + String(this.exp);
};

function PosExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = PosExpression.prototype = new UnaryExpression();
proto.constructor = PosExpression;

proto.toString = function ( ) {
    return "+ " + String(this.exp);
};

function NegExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = NegExpression.prototype = new UnaryExpression();
proto.constructor = NegExpression;

proto.toString = function ( ) {
    return "- " + String(this.exp);
};

function BitNotExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = BitNotExpression.prototype = new UnaryExpression();
proto.constructor = BitNotExpression;

proto.toString = function ( ) {
    return "~" + String(this.exp);
};

function NotExpression ( e ) {
    UnaryExpression.apply(this, arguments);
}

var proto = NotExpression.prototype = new UnaryExpression();
proto.constructor = NotExpression;

proto.toString = function ( ) {
    return "!" + String(this.exp);
};

function MulExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = MulExpression.prototype = new BinaryExpression();
proto.constructor = MulExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " * ", this.right, ")" ].join("");
};

function DivExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = DivExpression.prototype = new BinaryExpression();
proto.constructor = DivExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " / ", this.right, ")" ].join("");
};

function ModExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = ModExpression.prototype = new BinaryExpression();
proto.constructor = ModExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " % ", this.right, ")" ].join("");
};

function AddExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = AddExpression.prototype = new BinaryExpression();
proto.constructor = AddExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " + ", this.right, ")" ].join("");
};

function SubExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = SubExpression.prototype = new BinaryExpression();
proto.constructor = SubExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " - ", this.right, ")" ].join("");
};

function LShiftExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = LShiftExpression.prototype = new BinaryExpression();
proto.constructor = LShiftExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " << ", this.right, ")" ].join("");
};

function RShiftExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = RShiftExpression.prototype = new BinaryExpression();
proto.constructor = RShiftExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " >> ", this.right, ")" ].join("");
};

function URShiftExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = URShiftExpression.prototype = new BinaryExpression();
proto.constructor = URShiftExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " >>> ", this.right, ")" ].join("");
};

function LessThanExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = LessThanExpression.prototype = new BinaryExpression();
proto.constructor = LessThanExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " < ", this.right, ")" ].join("");
};

function GreaterThanExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = GreaterThanExpression.prototype = new BinaryExpression();
proto.constructor = GreaterThanExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " > ", this.right, ")" ].join("");
};

function LessEqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = LessEqualExpression.prototype = new BinaryExpression();
proto.constructor = LessEqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " <= ", this.right, ")" ].join("");
};

function GreaterEqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = GreaterEqualExpression.prototype = new BinaryExpression();
proto.constructor = GreaterEqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " >= ", this.right, ")" ].join("");
};

function InstanceofExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = InstanceofExpression.prototype = new BinaryExpression();
proto.constructor = InstanceofExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " instanceof ", this.right, ")" ].join("");
};

function InExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = InExpression.prototype = new BinaryExpression();
proto.constructor = InExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " in ", this.right, ")" ].join("");
};

function EqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = EqualExpression.prototype = new BinaryExpression();
proto.constructor = EqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " == ", this.right, ")" ].join("");
};

function NotEqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = NotEqualExpression.prototype = new BinaryExpression();
proto.constructor = NotEqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " != ", this.right, ")" ].join("");
};

function StrictEqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = StrictEqualExpression.prototype = new BinaryExpression();
proto.constructor = StrictEqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " === ", this.right, ")" ].join("");
};

function StrictNotEqualExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = StrictNotEqualExpression.prototype = new BinaryExpression();
proto.constructor = StrictNotEqualExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " !== ", this.right, ")" ].join("");
};

function BitAndExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = BitAndExpression.prototype = new BinaryExpression();
proto.constructor = BitAndExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " & ", this.right, ")" ].join("");
};

function BitXorExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = BitXorExpression.prototype = new BinaryExpression();
proto.constructor = BitXorExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " ^ ", this.right, ")" ].join("");
};

function BitOrExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = BitOrExpression.prototype = new BinaryExpression();
proto.constructor = BitOrExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " | ", this.right, ")" ].join("");
};

function AndExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = AndExpression.prototype = new BinaryExpression();
proto.constructor = AndExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " && ", this.right, ")" ].join("");
};

function OrExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = OrExpression.prototype = new BinaryExpression();
proto.constructor = OrExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " || ", this.right, ")" ].join("");
};

function ConditionalExpression ( c, t, f ) {
    this.cond = c;  // Expression
    this.texp = t;  // Expression
    this.fexp = f;  // Expression
}

var proto = ConditionalExpression.prototype = new Expression();
proto.constructor = ConditionalExpression;

proto.toString = function ( ) {
    return [ "(", this.cond, " ? ", this.texp, " : ", this.fexp, ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
    return this.cond.containsFunctionCall()
        || this.texp.containsFunctionCall()
        || this.fexp.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
    return this.cond.hasSideEffect()
        || this.texp.hasSideEffect()
        || this.fexp.hasSideEffect();
};

function AssignExpression ( left, right ) {
    // This is kind of interface. It just represents a set of classes.
    BinaryExpression.apply(this, arguments);
}

var proto = AssignExpression.prototype = new BinaryExpression();
proto.constructor = AssignExpression;

proto.hasSideEffect = function ( ) {
    return true;
};

function SimpleAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = SimpleAssignExpression.prototype = new AssignExpression();
proto.constructor = SimpleAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " = ", this.right, ")" ].join("");
};

function MulAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = MulAssignExpression.prototype = new AssignExpression();
proto.constructor = MulAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " *= ", this.right, ")" ].join("");
};

function DivAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = DivAssignExpression.prototype = new AssignExpression();
proto.constructor = DivAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " /= ", this.right, ")" ].join("");
};

function ModAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = ModAssignExpression.prototype = new AssignExpression();
proto.constructor = ModAssignExpression;

proto.toString = function ( ) {
    return [ "(",  this.left, " %= ", this.right, ")" ].join("");
};

function AddAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = AddAssignExpression.prototype = new AssignExpression();
proto.constructor = AddAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " += ", this.right, ")" ].join("");
};

function SubAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = SubAssignExpression.prototype = new AssignExpression();
proto.constructor = SubAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " -= ", this.right, ")" ].join("");
};

function LShiftAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = LShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = LShiftAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " <<= ", this.right, ")" ].join("");
};

function RShiftAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = RShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = RShiftAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " >>= ", this.right, ")" ].join("");
};

function URShiftAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = URShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = URShiftAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " >>>= ", this.right, ")" ].join("");
};

function BitAndAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = BitAndAssignExpression.prototype = new AssignExpression();
proto.constructor = BitAndAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " &= ", this.right, ")" ].join("");
};

function BitXorAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = BitXorAssignExpression.prototype = new AssignExpression();
proto.constructor = BitXorAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " ^= ", this.right, ")" ].join("");
};

function BitOrAssignExpression ( left, right ) {
    AssignExpression.apply(this, arguments);
}

var proto = BitOrAssignExpression.prototype = new AssignExpression();
proto.constructor = BitOrAssignExpression;

proto.toString = function ( ) {
    return [ "(", this.left, " |= ", this.right, ")" ].join("");
};

function CommaExpression ( left, right ) {
    BinaryExpression.apply(this, arguments);
}

var proto = CommaExpression.prototype = new BinaryExpression();
proto.constructor = CommaExpression;

proto.toString = function ( ) {
    return [ "(", this.left, ", ", this.right, ")" ].join("");
};

            return {
                StrictEqualExpression: StrictEqualExpression, BooleanLiteral: BooleanLiteral, OrExpression: OrExpression, NotExpression: NotExpression, ThisExpression: ThisExpression, BitAndAssignExpression: BitAndAssignExpression, DivExpression: DivExpression, BracketAccessor: BracketAccessor, CommaExpression: CommaExpression, BitAndExpression: BitAndExpression, MulExpression: MulExpression, EqualExpression: EqualExpression, CallExpression: CallExpression, FunctionExpression: FunctionExpression, Elision: Elision, PostIncExpression: PostIncExpression, InstanceofExpression: InstanceofExpression, NullLiteral: NullLiteral, BitXorAssignExpression: BitXorAssignExpression, URShiftExpression: URShiftExpression, ConditionalExpression: ConditionalExpression, Identifier: Identifier, UnaryExpression: UnaryExpression, BitOrAssignExpression: BitOrAssignExpression, DivAssignExpression: DivAssignExpression, VoidExpression: VoidExpression, TypeofExpression: TypeofExpression, NewExpression: NewExpression, MulAssignExpression: MulAssignExpression, BinaryExpression: BinaryExpression, TrueLiteral: TrueLiteral, AssignExpression: AssignExpression, SubExpression: SubExpression, PreDecExpression: PreDecExpression, RegExpLiteral: RegExpLiteral, DeleteExpression: DeleteExpression, FalseLiteral: FalseLiteral, BitNotExpression: BitNotExpression, GreaterEqualExpression: GreaterEqualExpression, LessEqualExpression: LessEqualExpression, ModExpression: ModExpression, StringLiteral: StringLiteral, LShiftAssignExpression: LShiftAssignExpression, SubAssignExpression: SubAssignExpression, LShiftExpression: LShiftExpression, ModAssignExpression: ModAssignExpression, URShiftAssignExpression: URShiftAssignExpression, NegExpression: NegExpression, PosExpression: PosExpression, AddAssignExpression: AddAssignExpression, ArrayInitializer: ArrayInitializer, LessThanExpression: LessThanExpression, NumberLiteral: NumberLiteral, StrictNotEqualExpression: StrictNotEqualExpression, RShiftExpression: RShiftExpression, InExpression: InExpression, BitOrExpression: BitOrExpression, AndExpression: AndExpression, PostDecExpression: PostDecExpression, ObjectInitializer: ObjectInitializer, RShiftAssignExpression: RShiftAssignExpression, Expression: Expression, DotAccessor: DotAccessor, Literal: Literal, SimpleAssignExpression: SimpleAssignExpression, BitXorExpression: BitXorExpression, AddExpression: AddExpression, GreaterThanExpression: GreaterThanExpression, NotEqualExpression: NotEqualExpression, PreIncExpression: PreIncExpression
            };
        }();
    }
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.StrictEqualExpression = StrictEqualExpression;
    this.Concurrent.Thread.Compiler.BooleanLiteral = BooleanLiteral;
    this.Concurrent.Thread.Compiler.OrExpression = OrExpression;
    this.Concurrent.Thread.Compiler.NotExpression = NotExpression;
    this.Concurrent.Thread.Compiler.ThisExpression = ThisExpression;
    this.Concurrent.Thread.Compiler.BitAndAssignExpression = BitAndAssignExpression;
    this.Concurrent.Thread.Compiler.DivExpression = DivExpression;
    this.Concurrent.Thread.Compiler.BracketAccessor = BracketAccessor;
    this.Concurrent.Thread.Compiler.CommaExpression = CommaExpression;
    this.Concurrent.Thread.Compiler.BitAndExpression = BitAndExpression;
    this.Concurrent.Thread.Compiler.MulExpression = MulExpression;
    this.Concurrent.Thread.Compiler.EqualExpression = EqualExpression;
    this.Concurrent.Thread.Compiler.CallExpression = CallExpression;
    this.Concurrent.Thread.Compiler.FunctionExpression = FunctionExpression;
    this.Concurrent.Thread.Compiler.Elision = Elision;
    this.Concurrent.Thread.Compiler.PostIncExpression = PostIncExpression;
    this.Concurrent.Thread.Compiler.InstanceofExpression = InstanceofExpression;
    this.Concurrent.Thread.Compiler.NullLiteral = NullLiteral;
    this.Concurrent.Thread.Compiler.BitXorAssignExpression = BitXorAssignExpression;
    this.Concurrent.Thread.Compiler.URShiftExpression = URShiftExpression;
    this.Concurrent.Thread.Compiler.ConditionalExpression = ConditionalExpression;
    this.Concurrent.Thread.Compiler.Identifier = Identifier;
    this.Concurrent.Thread.Compiler.UnaryExpression = UnaryExpression;
    this.Concurrent.Thread.Compiler.BitOrAssignExpression = BitOrAssignExpression;
    this.Concurrent.Thread.Compiler.DivAssignExpression = DivAssignExpression;
    this.Concurrent.Thread.Compiler.VoidExpression = VoidExpression;
    this.Concurrent.Thread.Compiler.TypeofExpression = TypeofExpression;
    this.Concurrent.Thread.Compiler.NewExpression = NewExpression;
    this.Concurrent.Thread.Compiler.MulAssignExpression = MulAssignExpression;
    this.Concurrent.Thread.Compiler.BinaryExpression = BinaryExpression;
    this.Concurrent.Thread.Compiler.TrueLiteral = TrueLiteral;
    this.Concurrent.Thread.Compiler.AssignExpression = AssignExpression;
    this.Concurrent.Thread.Compiler.SubExpression = SubExpression;
    this.Concurrent.Thread.Compiler.PreDecExpression = PreDecExpression;
    this.Concurrent.Thread.Compiler.RegExpLiteral = RegExpLiteral;
    this.Concurrent.Thread.Compiler.DeleteExpression = DeleteExpression;
    this.Concurrent.Thread.Compiler.FalseLiteral = FalseLiteral;
    this.Concurrent.Thread.Compiler.BitNotExpression = BitNotExpression;
    this.Concurrent.Thread.Compiler.GreaterEqualExpression = GreaterEqualExpression;
    this.Concurrent.Thread.Compiler.LessEqualExpression = LessEqualExpression;
    this.Concurrent.Thread.Compiler.ModExpression = ModExpression;
    this.Concurrent.Thread.Compiler.StringLiteral = StringLiteral;
    this.Concurrent.Thread.Compiler.LShiftAssignExpression = LShiftAssignExpression;
    this.Concurrent.Thread.Compiler.SubAssignExpression = SubAssignExpression;
    this.Concurrent.Thread.Compiler.LShiftExpression = LShiftExpression;
    this.Concurrent.Thread.Compiler.ModAssignExpression = ModAssignExpression;
    this.Concurrent.Thread.Compiler.URShiftAssignExpression = URShiftAssignExpression;
    this.Concurrent.Thread.Compiler.NegExpression = NegExpression;
    this.Concurrent.Thread.Compiler.PosExpression = PosExpression;
    this.Concurrent.Thread.Compiler.AddAssignExpression = AddAssignExpression;
    this.Concurrent.Thread.Compiler.ArrayInitializer = ArrayInitializer;
    this.Concurrent.Thread.Compiler.LessThanExpression = LessThanExpression;
    this.Concurrent.Thread.Compiler.NumberLiteral = NumberLiteral;
    this.Concurrent.Thread.Compiler.StrictNotEqualExpression = StrictNotEqualExpression;
    this.Concurrent.Thread.Compiler.RShiftExpression = RShiftExpression;
    this.Concurrent.Thread.Compiler.InExpression = InExpression;
    this.Concurrent.Thread.Compiler.BitOrExpression = BitOrExpression;
    this.Concurrent.Thread.Compiler.AndExpression = AndExpression;
    this.Concurrent.Thread.Compiler.PostDecExpression = PostDecExpression;
    this.Concurrent.Thread.Compiler.ObjectInitializer = ObjectInitializer;
    this.Concurrent.Thread.Compiler.RShiftAssignExpression = RShiftAssignExpression;
    this.Concurrent.Thread.Compiler.Expression = Expression;
    this.Concurrent.Thread.Compiler.DotAccessor = DotAccessor;
    this.Concurrent.Thread.Compiler.Literal = Literal;
    this.Concurrent.Thread.Compiler.SimpleAssignExpression = SimpleAssignExpression;
    this.Concurrent.Thread.Compiler.BitXorExpression = BitXorExpression;
    this.Concurrent.Thread.Compiler.AddExpression = AddExpression;
    this.Concurrent.Thread.Compiler.GreaterThanExpression = GreaterThanExpression;
    this.Concurrent.Thread.Compiler.NotEqualExpression = NotEqualExpression;
    this.Concurrent.Thread.Compiler.PreIncExpression = PreIncExpression;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( this.Concurrent.Thread.Compiler.Token === undefined ) this.Concurrent.Thread.Compiler.Token = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Roger Lawrence
 *   Mike McCabe
 *   Igor Bukanov
 *   Milen Nankov
 *   Daisuke Maki
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * This file is based on the file Token.java in Rhino 1.6R5.
 */

NAMESPACE = 'Concurrent.Thread.Compiler';

var Token = {};

// Although Token is in fact a namespace, we here implements it
// "manually" because of efficiency.

// start enum
Token.ERROR          = -1; // well-known as the only code < EOF
Token.EOF            = 0;  // end of file token - (not EOF_CHAR)
Token.EOL            = 1;  // end of line

// Interpreter reuses the following as bytecodes
Token.FIRST_BYTECODE_TOKEN    = 2;

Token.ENTERWITH      = 2;
Token.LEAVEWITH      = 3;
Token.RETURN         = 4;
Token.GOTO           = 5;
Token.IFEQ           = 6;
Token.IFNE           = 7;
Token.SETNAME        = 8;
Token.BITOR          = 9;
Token.BITXOR         = 10;
Token.BITAND         = 11;
Token.EQ             = 12;
Token.NE             = 13;
Token.LT             = 14;
Token.LE             = 15;
Token.GT             = 16;
Token.GE             = 17;
Token.LSH            = 18;
Token.RSH            = 19;
Token.URSH           = 20;
Token.ADD            = 21;
Token.SUB            = 22;
Token.MUL            = 23;
Token.DIV            = 24;
Token.MOD            = 25;
Token.NOT            = 26;
Token.BITNOT         = 27;
Token.POS            = 28;
Token.NEG            = 29;
Token.NEW            = 30;
Token.DELPROP        = 31;
Token.TYPEOF         = 32;
Token.GETPROP        = 33;
Token.SETPROP        = 34;
Token.GETELEM        = 35;
Token.SETELEM        = 36;
Token.CALL           = 37;
Token.NAME           = 38;
Token.NUMBER         = 39;
Token.STRING         = 40;
Token.NULL           = 41;
Token.THIS           = 42;
Token.FALSE          = 43;
Token.TRUE           = 44;
Token.SHEQ           = 45;   // shallow equality (===)
Token.SHNE           = 46;   // shallow inequality (!==)
Token.REGEXP         = 47;
Token.BINDNAME       = 48;
Token.THROW          = 49;
Token.RETHROW        = 50; // rethrow caught execetion: catch (e if ) use it
Token.IN             = 51;
Token.INSTANCEOF     = 52;
Token.LOCAL_LOAD     = 53;
Token.GETVAR         = 54;
Token.SETVAR         = 55;
Token.CATCH_SCOPE    = 56;
Token.ENUM_INIT_KEYS = 57;
Token.ENUM_INIT_VALUES = 58;
Token.ENUM_NEXT      = 59;
Token.ENUM_ID        = 60;
Token.THISFN         = 61;
Token.RETURN_RESULT  = 62; // to return prevoisly stored return result
Token.ARRAYLIT       = 63; // array literal
Token.OBJECTLIT      = 64; // object literal
Token.GET_REF        = 65; // *reference
Token.SET_REF        = 66; // *reference    : something
Token.DEL_REF        = 67; // delete reference
Token.REF_CALL       = 68; // f(args)    = something or f(args)++
Token.REF_SPECIAL    = 69; // reference for special properties like __proto

// For XML support:
Token.DEFAULTNAMESPACE = 70; // default xml namespace =
Token.ESCXMLATTR     = 71;
Token.ESCXMLTEXT     = 72;
Token.REF_MEMBER     = 73; // Reference for x.@y, x..y etc.
Token.REF_NS_MEMBER  = 74; // Reference for x.ns::y, x..ns::y etc.
Token.REF_NAME       = 75; // Reference for @y, @[y] etc.
Token.REF_NS_NAME    = 76; // Reference for ns::y, @ns::y@[y] etc.

// End of interpreter bytecodes

Token.LAST_BYTECODE_TOKEN = Token.REF_NS_NAME;

Token.TRY            = 77;
Token.SEMI           = 78;  // semicolon
Token.LB             = 79;  // left and right brackets
Token.RB             = 80;
Token.LC             = 81;  // left and right curlies (braces)
Token.RC             = 82;
Token.LP             = 83;  // left and right parentheses
Token.RP             = 84;
Token.COMMA          = 85;  // comma operator

Token.ASSIGN         = 86;  // simple assignment  (=)
Token.ASSIGN_BITOR   = 87;  // |=
Token.ASSIGN_BITXOR  = 88;  // ^=
Token.ASSIGN_BITAND  = 89;  // |=
Token.ASSIGN_LSH     = 90;  // <<=
Token.ASSIGN_RSH     = 91;  // >>=
Token.ASSIGN_URSH    = 92;  // >>>=
Token.ASSIGN_ADD     = 93;  // +=
Token.ASSIGN_SUB     = 94;  // -=
Token.ASSIGN_MUL     = 95;  // *=
Token.ASSIGN_DIV     = 96;  // /=
Token.ASSIGN_MOD     = 97;  // %=

Token.FIRST_ASSIGN   = Token.ASSIGN;
Token.LAST_ASSIGN    = Token.ASSIGN_MOD;

Token.HOOK           = 98; // conditional (?:)
Token.COLON          = 99;
Token.OR             = 100; // logical or (||)
Token.AND            = 101; // logical and (&&)
Token.INC            = 102; // increment/decrement (++ --)
Token.DEC            = 103;
Token.DOT            = 104; // member operator (.)
Token.FUNCTION       = 105; // function keyword
Token.EXPORT         = 106; // export keyword
Token.IMPORT         = 107; // import keyword
Token.IF             = 108; // if keyword
Token.ELSE           = 109; // else keyword
Token.SWITCH         = 110; // switch keyword
Token.CASE           = 111; // case keyword
Token.DEFAULT        = 112; // default keyword
Token.WHILE          = 113; // while keyword
Token.DO             = 114; // do keyword
Token.FOR            = 115; // for keyword
Token.BREAK          = 116; // break keyword
Token.CONTINUE       = 117; // continue keyword
Token.VAR            = 118; // var keyword
Token.WITH           = 119; // with keyword
Token.CATCH          = 120; // catch keyword
Token.FINALLY        = 121; // finally keyword
Token.VOID           = 122; // void keyword
Token.RESERVED       = 123; // reserved keywords

Token.EMPTY          = 124;

/* types used for the parse tree - these never get returned
 * by the scanner.
 */

Token.BLOCK          = 125; // statement block
Token.LABEL          = 126; // label
Token.TARGET         = 127;
Token.LOOP           = 128;
Token.EXPR_VOID      = 129; // expression statement in functions
Token.EXPR_RESULT    = 130; // expression statement in scripts
Token.JSR            = 131;
Token.SCRIPT         = 132; // top-level node for entire script
Token.TYPEOFNAME     = 133; // for typeof(simple-name)
Token.USE_STACK      = 134;
Token.SETPROP_OP     = 135; // x.y op= something
Token.SETELEM_OP     = 136; // x[y] op= something
Token.LOCAL_BLOCK    = 137;
Token.SET_REF_OP     = 138; // *reference op= something

// For XML support:
Token.DOTDOT         = 139;  // member operator (..)
Token.COLONCOLON     = 140;  // namespace::name
Token.XML            = 141;  // XML type
Token.DOTQUERY       = 142;  // .() -- e.g., x.emps.emp.(name == "terry")
Token.XMLATTR        = 143;  // @
Token.XMLEND         = 144;

// Optimizer-only-tokens
Token.TO_OBJECT      = 145;
Token.TO_DOUBLE      = 146;

Token.LAST_TOKEN     = 146;

Token.name = function ( token )
{
    if ( !Kit.printTrees ) return String(token);
    with ( Token ) {
        switch ( token ) {
          case ERROR:           return "ERROR";
          case EOF:             return "EOF";
          case EOL:             return "EOL";
          case ENTERWITH:       return "ENTERWITH";
          case LEAVEWITH:       return "LEAVEWITH";
          case RETURN:          return "RETURN";
          case GOTO:            return "GOTO";
          case IFEQ:            return "IFEQ";
          case IFNE:            return "IFNE";
          case SETNAME:         return "SETNAME";
          case BITOR:           return "BITOR";
          case BITXOR:          return "BITXOR";
          case BITAND:          return "BITAND";
          case EQ:              return "EQ";
          case NE:              return "NE";
          case LT:              return "LT";
          case LE:              return "LE";
          case GT:              return "GT";
          case GE:              return "GE";
          case LSH:             return "LSH";
          case RSH:             return "RSH";
          case URSH:            return "URSH";
          case ADD:             return "ADD";
          case SUB:             return "SUB";
          case MUL:             return "MUL";
          case DIV:             return "DIV";
          case MOD:             return "MOD";
          case NOT:             return "NOT";
          case BITNOT:          return "BITNOT";
          case POS:             return "POS";
          case NEG:             return "NEG";
          case NEW:             return "NEW";
          case DELPROP:         return "DELPROP";
          case TYPEOF:          return "TYPEOF";
          case GETPROP:         return "GETPROP";
          case SETPROP:         return "SETPROP";
          case GETELEM:         return "GETELEM";
          case SETELEM:         return "SETELEM";
          case CALL:            return "CALL";
          case NAME:            return "NAME";
          case NUMBER:          return "NUMBER";
          case STRING:          return "STRING";
          case NULL:            return "NULL";
          case THIS:            return "THIS";
          case FALSE:           return "FALSE";
          case TRUE:            return "TRUE";
          case SHEQ:            return "SHEQ";
          case SHNE:            return "SHNE";
          case REGEXP:          return "OBJECT";
          case BINDNAME:        return "BINDNAME";
          case THROW:           return "THROW";
          case RETHROW:         return "RETHROW";
          case IN:              return "IN";
          case INSTANCEOF:      return "INSTANCEOF";
          case LOCAL_LOAD:      return "LOCAL_LOAD";
          case GETVAR:          return "GETVAR";
          case SETVAR:          return "SETVAR";
          case CATCH_SCOPE:     return "CATCH_SCOPE";
          case ENUM_INIT_KEYS:  return "ENUM_INIT_KEYS";
          case ENUM_INIT_VALUES:  return "ENUM_INIT_VALUES";
          case ENUM_NEXT:       return "ENUM_NEXT";
          case ENUM_ID:         return "ENUM_ID";
          case THISFN:          return "THISFN";
          case RETURN_RESULT:   return "RETURN_RESULT";
          case ARRAYLIT:        return "ARRAYLIT";
          case OBJECTLIT:       return "OBJECTLIT";
          case GET_REF:         return "GET_REF";
          case SET_REF:         return "SET_REF";
          case DEL_REF:         return "DEL_REF";
          case REF_CALL:        return "REF_CALL";
          case REF_SPECIAL:     return "REF_SPECIAL";
          case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
          case ESCXMLTEXT:      return "ESCXMLTEXT";
          case ESCXMLATTR:      return "ESCXMLATTR";
          case REF_MEMBER:      return "REF_MEMBER";
          case REF_NS_MEMBER:   return "REF_NS_MEMBER";
          case REF_NAME:        return "REF_NAME";
          case REF_NS_NAME:     return "REF_NS_NAME";
          case TRY:             return "TRY";
          case SEMI:            return "SEMI";
          case LB:              return "LB";
          case RB:              return "RB";
          case LC:              return "LC";
          case RC:              return "RC";
          case LP:              return "LP";
          case RP:              return "RP";
          case COMMA:           return "COMMA";
          case ASSIGN:          return "ASSIGN";
          case ASSIGN_BITOR:    return "ASSIGN_BITOR";
          case ASSIGN_BITXOR:   return "ASSIGN_BITXOR";
          case ASSIGN_BITAND:   return "ASSIGN_BITAND";
          case ASSIGN_LSH:      return "ASSIGN_LSH";
          case ASSIGN_RSH:      return "ASSIGN_RSH";
          case ASSIGN_URSH:     return "ASSIGN_URSH";
          case ASSIGN_ADD:      return "ASSIGN_ADD";
          case ASSIGN_SUB:      return "ASSIGN_SUB";
          case ASSIGN_MUL:      return "ASSIGN_MUL";
          case ASSIGN_DIV:      return "ASSIGN_DIV";
          case ASSIGN_MOD:      return "ASSIGN_MOD";
          case HOOK:            return "HOOK";
          case COLON:           return "COLON";
          case OR:              return "OR";
          case AND:             return "AND";
          case INC:             return "INC";
          case DEC:             return "DEC";
          case DOT:             return "DOT";
          case FUNCTION:        return "FUNCTION";
          case EXPORT:          return "EXPORT";
          case IMPORT:          return "IMPORT";
          case IF:              return "IF";
          case ELSE:            return "ELSE";
          case SWITCH:          return "SWITCH";
          case CASE:            return "CASE";
          case DEFAULT:         return "DEFAULT";
          case WHILE:           return "WHILE";
          case DO:              return "DO";
          case FOR:             return "FOR";
          case BREAK:           return "BREAK";
          case CONTINUE:        return "CONTINUE";
          case VAR:             return "VAR";
          case WITH:            return "WITH";
          case CATCH:           return "CATCH";
          case FINALLY:         return "FINALLY";
          case RESERVED:        return "RESERVED";
          case EMPTY:           return "EMPTY";
          case BLOCK:           return "BLOCK";
          case LABEL:           return "LABEL";
          case TARGET:          return "TARGET";
          case LOOP:            return "LOOP";
          case EXPR_VOID:       return "EXPR_VOID";
          case EXPR_RESULT:     return "EXPR_RESULT";
          case JSR:             return "JSR";
          case SCRIPT:          return "SCRIPT";
          case TYPEOFNAME:      return "TYPEOFNAME";
          case USE_STACK:       return "USE_STACK";
          case SETPROP_OP:      return "SETPROP_OP";
          case SETELEM_OP:      return "SETELEM_OP";
          case LOCAL_BLOCK:     return "LOCAL_BLOCK";
          case SET_REF_OP:      return "SET_REF_OP";
          case DOTDOT:          return "DOTDOT";
          case COLONCOLON:      return "COLONCOLON";
          case XML:             return "XML";
          case DOTQUERY:        return "DOTQUERY";
          case XMLATTR:         return "XMLATTR";
          case XMLEND:          return "XMLEND";
          case TO_OBJECT:       return "TO_OBJECT";
          case TO_DOUBLE:       return "TO_DOUBLE";
        }
    }
    // Token without name
    Kit.codeBug(token);
};

            return {
                Token: Token
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.Token = Token;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.Statement === undefined ) this.Concurrent.Thread.Compiler.Statement = undefined;
    if ( this.Concurrent.Thread.Compiler.EmptyStatement === undefined ) this.Concurrent.Thread.Compiler.EmptyStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.Block === undefined ) this.Concurrent.Thread.Compiler.Block = undefined;
    if ( this.Concurrent.Thread.Compiler.ExpStatement === undefined ) this.Concurrent.Thread.Compiler.ExpStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.VarStatement === undefined ) this.Concurrent.Thread.Compiler.VarStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.IfStatement === undefined ) this.Concurrent.Thread.Compiler.IfStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.IfElseStatement === undefined ) this.Concurrent.Thread.Compiler.IfElseStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.DoWhileStatement === undefined ) this.Concurrent.Thread.Compiler.DoWhileStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.WhileStatement === undefined ) this.Concurrent.Thread.Compiler.WhileStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForStatement === undefined ) this.Concurrent.Thread.Compiler.ForStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForVarStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForInStatement === undefined ) this.Concurrent.Thread.Compiler.ForInStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForInVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForInVarStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForEachStatement === undefined ) this.Concurrent.Thread.Compiler.ForEachStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ForEachVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForEachVarStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ContinueStatement === undefined ) this.Concurrent.Thread.Compiler.ContinueStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.BreakStatement === undefined ) this.Concurrent.Thread.Compiler.BreakStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.ReturnStatement === undefined ) this.Concurrent.Thread.Compiler.ReturnStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.WithStatement === undefined ) this.Concurrent.Thread.Compiler.WithStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.SwitchStatement === undefined ) this.Concurrent.Thread.Compiler.SwitchStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.CaseClause === undefined ) this.Concurrent.Thread.Compiler.CaseClause = undefined;
    if ( this.Concurrent.Thread.Compiler.DefaultClause === undefined ) this.Concurrent.Thread.Compiler.DefaultClause = undefined;
    if ( this.Concurrent.Thread.Compiler.ThrowStatement === undefined ) this.Concurrent.Thread.Compiler.ThrowStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.TryCatchStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.TryFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryFinallyStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.TryCatchFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchFinallyStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.TryCatchListStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchListStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.CatchGuard === undefined ) this.Concurrent.Thread.Compiler.CatchGuard = undefined;
    if ( this.Concurrent.Thread.Compiler.FunctionDeclaration === undefined ) this.Concurrent.Thread.Compiler.FunctionDeclaration = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

function Statement ( labels, lineno, source ) {
    // This is kind of abstract class.
    this.labels = labels;  // array of Identifier  # labels directly qualifying this statement
    this.lineno = lineno;  // Number (optional)    # line no.
    this.source = source;  // String (optional)    # file-name, URL, ...etc
}

Statement.prototype.toString = function ( ) {
    Kit.codeBug();
};

// kind of final protected method.
// Use this like: labelsToString.call(obj, arg0, arg1 ...)
function labelsToString ( ) {
    var buf = [];
    for ( var i=0;  i < this.labels.length;  i++ ) {
        buf.push(this.labels[i], ": ");
    }
    return buf.join("");
}

function EmptyStatement ( labels, lineno, source ) {
    Statement.call(this, labels, lineno, source);
}

var proto = EmptyStatement.prototype = new Statement();
proto.constructor = EmptyStatement;

proto.toString = function ( ) {
    return labelsToString.call(this) + ";";
};

function Block ( labels, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.body = body;  // cons-list of Statement
}

var proto = Block.prototype = new Statement();
proto.constructor = Block;

proto.toString = function ( ) {
    var buf = [labelsToString.call(this), "{"];
    this.body.forEach(function( it ){
        buf.push(it);
    });
    buf.push("}");
    return buf.join("\n");
};

function ExpStatement ( labels, exp, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.exp = exp;  // Expression
}

var proto = ExpStatement.prototype = new Statement();
proto.constructor = ExpStatement;

proto.toString = function ( ) {
    return labelsToString.call(this) + String(this.exp) + ";";
};

proto.containsFunctionCall = function ( ) {
    return this.exp.containsFunctionCall();
};

function VarStatement ( labels, decls, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.decls = decls;  // array of {id: Identifier,  exp: Expression or null}
}

var proto = VarStatement.prototype = new Statement();
proto.constructor = VarStatement;

proto.toString = function ( ) {
    var buf = [];
    for ( var i=0;  i < this.decls.length;  i++ ) {
        if ( this.decls[i].exp ) {
            buf.push( [ this.decls[i].id, "=", this.decls[i].exp ].join("") );
        }
        else {
            buf.push( this.decls[i].id );
        }
    }
    return [ labelsToString.call(this),
             "var ",
             buf.join(", "),
             ";",
           ].join("");
};

proto.containsFunctionCall = function ( ) {
    for ( var i=0;  i < this.decls.length;  i++ ) {
        if ( this.decls[i].exp && this.decls[i].exp.containsFunctionCall() ) {
            return true;
        }
    }
    return false;
};

function IfStatement ( labels, cond, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.cond = cond;  // Expression
    this.body = body;  // Statement
}

var proto = IfStatement.prototype = new Statement();
proto.constructor = IfStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "if (",
             this.cond,
             ") ",
             this.body
           ].join("");
};

function IfElseStatement ( labels, cond, tbody, fbody, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.cond  = cond;   // Expression
    this.tbody = tbody;  // Statement
    this.fbody = fbody;  // Statement
}

var proto = IfElseStatement.prototype = new Statement();
proto.constructor = IfElseStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "if (",
             this.cond,
             ") ",
             this.tbody,
             "\n",
             "else ",
             this.fbody
           ].join("");
};

function DoWhileStatement ( labels, body, cond, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.body = body;  // Statement
    this.cond = cond;  // Expression
}

var proto = DoWhileStatement.prototype = new Statement();
proto.constructor = DoWhileStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "do ",
             this.body,
             " while (",
             this.cond,
             ");"
           ].join("");
};

function WhileStatement ( labels, cond, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.cond = cond;  // Expression
    this.body = body;  // Statement
}

var proto = WhileStatement.prototype = new Statement();
proto.constructor = WhileStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "while (",
             this.cond,
             ") ",
             this.body
           ].join("");
};

function ForStatement ( labels, init, cond, incr, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.init = init;  // Expression or null
    this.cond = cond;  // Expression or null
    this.incr = incr;  // Expression or null
    this.body = body;  // Statement
}

var proto = ForStatement.prototype = new Statement();
proto.constructor = ForStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for (",
             this.init ? this.init : "", "; ",
             this.cond ? this.cond : "", "; ",
             this.incr ? this.incr : "",
             ") ",
             this.body
           ].join("");
};

function ForVarStatement ( labels, decls, cond, incr, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.decls = decls;  // array of {id: Identifier,  exp: Expression or null}
    this.cond  = cond;   // Expression or null
    this.incr  = incr;   // Expression or null
    this.body  = body;   // Statement
}

var proto = ForVarStatement.prototype = new Statement();
proto.constructor = ForVarStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for (",
             (this.decls.length ? new VarStatement([], this.decls) : ";"), " ",
             this.cond ? this.cond : "", "; ",
             this.incr ? this.incr : "",
             ") ",
             this.body
           ].join("");
};

function ForInStatement ( labels, lhs, exp, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.lhs  = lhs;   // Identifier or DotAccessor or BracketAccessor
    this.exp  = exp;   // Expression
    this.body = body;  // Statement
}

var proto = ForInStatement.prototype = new Statement();
proto.constructor = ForInStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for (", this.lhs, " in ", this.exp, ") ",
             this.body
           ].join("");
};

function ForInVarStatement ( labels, decl, exp, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.decl = decl;  // {id: Identifier,  exp: Expression or null}
    this.exp  = exp;   // Expression
    this.body = body;  // Statement
}

var proto = ForInVarStatement.prototype = new Statement();
proto.constructor = ForInVarStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for ( var ",
             this.decl.exp ? String(this.decl.id) + "=" + String(this.decl.exp)
                           : String(this.decl.id),
             " in ",
             this.exp,
             ") ",
             this.body
           ].join("");
};

// Mozilla extention "for each ( ... in ... )"

function ForEachStatement ( labels, lhs, exp, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.lhs  = lhs;   // Identifier or DotAccessor or BracketAccessor
    this.exp  = exp;   // Expression
    this.body = body;  // Statement
}

var proto = ForEachStatement.prototype = new Statement();
proto.constructor = ForEachStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for each (", this.lhs, " in ", this.exp, ") ",
             this.body
           ].join("");
};

function ForEachVarStatement ( labels, decl, exp, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.decl = decl;  // {id: Identifier,  exp: Expression or null}
    this.exp  = exp;   // Expression
    this.body = body;  // Statement
}

var proto = ForEachVarStatement.prototype = new Statement();
proto.constructor = ForEachVarStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "for each ( var ",
             this.decl.exp ? String(this.decl.id) + "=" + String(this.decl.exp)
                           : String(this.decl.id),
             " in ",
             this.exp,
             ") ",
             this.body
           ].join("");
};

function ContinueStatement ( labels, target, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.target = target;  // Identifier or null
}

var proto = ContinueStatement.prototype = new Statement();
proto.constructor = ContinueStatement;

proto.toString = function ( ) {
    var buf = [labelsToString.call(this), "continue"];
    if ( this.target ) buf.push(" ", this.target);
    buf.push(";");
    return buf.join("");
};

function BreakStatement ( labels, target, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.target = target;  // Identifier or null
}

var proto = BreakStatement.prototype = new Statement();
proto.constructor = BreakStatement;

proto.toString = function ( ) {
    var buf = [labelsToString.call(this), "break"];
    if ( this.target ) buf.push(" ", this.target);
    buf.push(";");
    return buf.join("");
};

function ReturnStatement ( labels, exp, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.exp = exp;  // Expression or null
}

var proto = ReturnStatement.prototype = new Statement();
proto.constructor = ReturnStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "return ",
             this.exp ? this.exp : "",
             ";"
           ].join("");
};

function WithStatement ( labels, exp, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.exp  = exp;   // Expression
    this.body = body;  // Statement
}

var proto = WithStatement.prototype = new Statement();
proto.constructor = WithStatement;

proto.toString = function ( ) {
    return [ "with (", this.exp, ") ", this.body ].join("");
};

function SwitchStatement ( labels, exp, clauses, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.exp     = exp;      // Expression
    this.clauses = clauses;  // cons-list of (CaseClause or DefaultClause)
}

var proto = SwitchStatement.prototype = new Statement();
proto.constructor = SwitchStatement;

proto.toString = function ( ) {
    var buf = [ "switch ( ", this.exp, ") {\n"];
    this.clauses.forEach(function( it ){
        buf.push(it, "\n");
    });
    buf.push("}");
    return buf.join("");
};

function CaseClause ( exp, body, lineno, source ) {
    this.exp    = exp;     // Expression
    this.body   = body;    // cons-list of Statement
    this.lineno = lineno;  // Number (optional)
    this.source = source;  // String (optional)
}

CaseClause.prototype.toString = function ( ) {
    var buf = ["case ", this.exp, ":\n"];
    this.body.forEach(function( it ){
        buf.push(it, "\n");
    });
    return buf.join("");
};

function DefaultClause ( body, lineno, source ) {
    this.body   = body;    // cons-list of Statement
    this.lineno = lineno;  // Number (optional)
    this.source = source;  // String (optional)
}

DefaultClause.prototype.toString = function ( ) {
    var buf = ["default:\n"];
    this.body.forEach(function( it ){
        buf.push(it, "\n");
    });
    return buf.join("");
};

function ThrowStatement ( labels, exp, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.exp = exp;  // Expression
}

var proto = ThrowStatement.prototype = new Statement();
proto.constructor = ThrowStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "throw ", this.exp, ";"
           ].join("");
};

function TryCatchStatement ( labels, tryBlock, variable, catchBlock, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.tryBlock   = tryBlock;    // Block
    this.variable   = variable;    // Identifier
    this.catchBlock = catchBlock;  // Block
}

var proto = TryCatchStatement.prototype = new Statement();
proto.constructor = TryCatchStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "try ", this.tryBlock, "\n",
             "catch (", this.variable, ") ", this.catchBlock
           ].join("");
};

function TryFinallyStatement ( labels, tryBlock, finallyBlock, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.tryBlock     = tryBlock;      // Block
    this.finallyBlock = finallyBlock;  // Block
}

var proto = TryFinallyStatement.prototype = new Statement();
proto.constructor = TryFinallyStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "try ", this.tryBlock, "\n",
             "finally ", this.finallyBlock
           ].join("");
};

function TryCatchFinallyStatement ( labels, tryBlock, variable, catchBlock, finallyBlock, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.tryBlock     = tryBlock;      // Block
    this.variable     = variable;      // Identifier
    this.catchBlock   = catchBlock;    // Block
    this.finallyBlock = finallyBlock;  // Block
}

var proto = TryCatchFinallyStatement.prototype = new Statement();
proto.constructor = TryCatchFinallyStatement;

proto.toString = function ( ) {
    return [ labelsToString.call(this),
             "try ", this.tryBlock, "\n",
             "catch (", this.variable, ") ", this.catchBlock, "\n",
             "finally ", this.finallyBlock
           ].join("");
};

function TryCatchListStatement ( labels, tryBlock, catchList, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.tryBlock  = tryBlock;   // Block
    this.catchList = catchList;  // cons-list of CatchGuard
}

var proto = TryCatchListStatement.prototype = new Statement();
proto.constructor = TryCatchListStatement;

proto.toString = function ( ) {
    var buf = [ labelsToString.call(this),
                "try ", this.tryBlock, "\n" ];
    this.catchList.forEach(function( it ){
        buf.push(it);
    });
    return buf.join("");
};

function TryCatchListFinallyStatement ( labels, tryBlock, catchList, finallyBlock, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.tryBlock     = tryBlock;      // Block
    this.catchList    = catchList;     // cons-list of CatchGuard
    this.finallyBlock = finallyBlock;  // Block
}

var proto = TryCatchListFinallyStatement.prototype = new Statement();
proto.constructor = TryCatchListFinallyStatement;

proto.toString = function ( ) {
    var buf = [ labelsToString.call(this),
                "try ", this.tryBlock, "\n" ];
    this.catchList.forEach(function( it ){
        buf.push(it);
    });
    buf.push("finally ", this.finallyBlock);
    return buf.join("");
};

function CatchGuard ( variable, cond, block, lineno, source ) {
    this.variable = variable;  // Identifier
    this.cond     = cond;      // Expression or null (null means this is default catch clause)
    this.block    = block;     // Block
    this.lineno   = lineno;    // Number (optional)
    this.source   = source;    // String (optional)
}

CatchGuard.prototype.toString = function ( ) {
    var buf = ["catch ( ", this.variable];
    if ( this.cond ) buf.push(" if ", this.cond);
    buf.push(" )", this.block);
    return buf.join("");
};

function FunctionDeclaration ( labels, name, params, body, lineno, source ) {
    Statement.call(this, labels, lineno, source);
    this.name   = name;    // Identifier
    this.params = params;  // array of Identifier
    this.body   = body;    // cons-list of Statement
}

var proto = FunctionDeclaration.prototype = new Statement();
proto.constructor = FunctionDeclaration;

proto.toString = function ( ) {
    var buf = [ "function ", this.name,
                " (", this.params.join(", "), ") {\n" ];
    this.body.forEach(function( it ){
        buf.push(it, "\n");
    });
    buf.push("}");
    return buf.join("");
};

            return {
                CatchGuard: CatchGuard, Block: Block, IfStatement: IfStatement, FunctionDeclaration: FunctionDeclaration, ForVarStatement: ForVarStatement, IfElseStatement: IfElseStatement, TryFinallyStatement: TryFinallyStatement, TryCatchFinallyStatement: TryCatchFinallyStatement, ThrowStatement: ThrowStatement, ForEachStatement: ForEachStatement, EmptyStatement: EmptyStatement, TryCatchStatement: TryCatchStatement, WithStatement: WithStatement, ExpStatement: ExpStatement, ReturnStatement: ReturnStatement, Statement: Statement, ForInVarStatement: ForInVarStatement, BreakStatement: BreakStatement, TryCatchListStatement: TryCatchListStatement, DoWhileStatement: DoWhileStatement, ForInStatement: ForInStatement, DefaultClause: DefaultClause, VarStatement: VarStatement, ContinueStatement: ContinueStatement, TryCatchListFinallyStatement: TryCatchListFinallyStatement, WhileStatement: WhileStatement, SwitchStatement: SwitchStatement, ForEachVarStatement: ForEachVarStatement, CaseClause: CaseClause, ForStatement: ForStatement
            };
        }();
    }
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CatchGuard = CatchGuard;
    this.Concurrent.Thread.Compiler.Block = Block;
    this.Concurrent.Thread.Compiler.IfStatement = IfStatement;
    this.Concurrent.Thread.Compiler.FunctionDeclaration = FunctionDeclaration;
    this.Concurrent.Thread.Compiler.ForVarStatement = ForVarStatement;
    this.Concurrent.Thread.Compiler.IfElseStatement = IfElseStatement;
    this.Concurrent.Thread.Compiler.TryFinallyStatement = TryFinallyStatement;
    this.Concurrent.Thread.Compiler.TryCatchFinallyStatement = TryCatchFinallyStatement;
    this.Concurrent.Thread.Compiler.ThrowStatement = ThrowStatement;
    this.Concurrent.Thread.Compiler.ForEachStatement = ForEachStatement;
    this.Concurrent.Thread.Compiler.EmptyStatement = EmptyStatement;
    this.Concurrent.Thread.Compiler.TryCatchStatement = TryCatchStatement;
    this.Concurrent.Thread.Compiler.WithStatement = WithStatement;
    this.Concurrent.Thread.Compiler.ExpStatement = ExpStatement;
    this.Concurrent.Thread.Compiler.ReturnStatement = ReturnStatement;
    this.Concurrent.Thread.Compiler.Statement = Statement;
    this.Concurrent.Thread.Compiler.ForInVarStatement = ForInVarStatement;
    this.Concurrent.Thread.Compiler.BreakStatement = BreakStatement;
    this.Concurrent.Thread.Compiler.TryCatchListStatement = TryCatchListStatement;
    this.Concurrent.Thread.Compiler.DoWhileStatement = DoWhileStatement;
    this.Concurrent.Thread.Compiler.ForInStatement = ForInStatement;
    this.Concurrent.Thread.Compiler.DefaultClause = DefaultClause;
    this.Concurrent.Thread.Compiler.VarStatement = VarStatement;
    this.Concurrent.Thread.Compiler.ContinueStatement = ContinueStatement;
    this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement = TryCatchListFinallyStatement;
    this.Concurrent.Thread.Compiler.WhileStatement = WhileStatement;
    this.Concurrent.Thread.Compiler.SwitchStatement = SwitchStatement;
    this.Concurrent.Thread.Compiler.ForEachVarStatement = ForEachVarStatement;
    this.Concurrent.Thread.Compiler.CaseClause = CaseClause;
    this.Concurrent.Thread.Compiler.ForStatement = ForStatement;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( this.Concurrent.Thread.Compiler.IdentifierMap === undefined ) this.Concurrent.Thread.Compiler.IdentifierMap = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var hasOwnProperty = Object.prototype.hasOwnProperty;

function IdentifierMap ( ) {
    this._map = {};
}

var proto = IdentifierMap.prototype;

proto.clone = function clone ( ) {
    var c = new IdentifierMap();
    for ( var i in this._map ) {
        if ( hasOwnProperty.call(this._map, i) ) c._map[i] = this._map[i];
    }
    return c;
};

proto.exists = function ( /* variable arguments */ ) {
    for ( var i=0;  i < arguments.length;  i++ ) {
        var key = arguments[i];
        if ( !(key instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
        if ( !hasOwnProperty.call(this._map, key.valueOf()) ) return false;
    }
    return true;
};

proto.get = function ( k ) {
    if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
    var s = k.valueOf();
    if ( !hasOwnProperty.call(this._map, s) ) return undefined;
    return this._map[s].value;
};

proto.put = function ( k, v ) {
    if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
    this._map[k.valueOf()] = {id: k, value: v};
};

proto.remove = function ( k ) {
    if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
    return delete this._map[k.valueOf()];
};

proto.keys = function ( ) {
    var set = new IdentifierSet();
    for ( var i in this._map ) {
        if ( hasOwnProperty.call(this._map, i) ) set.add(this._map[i].id);
    }
    return set;
};

proto.values = function ( ) {
    var vals = [];
    for ( var i in this._map ) {
        if ( hasOwnProperty.call(this._map, i) ) vals.push(this._map[i].value);
    }
    return vals;
};

            return {
                IdentifierMap: IdentifierMap
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.IdentifierMap = IdentifierMap;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( this.Concurrent.Thread.Compiler.TokenStream === undefined ) this.Concurrent.Thread.Compiler.TokenStream = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Roger Lawrence
 *   Mike McCabe
 *   Igor Bukanov
 *   Ethan Hugg
 *   Terry Lucas
 *   Milen Nankov
 *   Daisuke Maki
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * This file is based on the file TokenStream.java in Rhino 1.6R5.
 */

NAMESPACE = 'Concurrent.Thread.Compiler';

/*
 * For chars - because we need something out-of-range
 * to check.  (And checking EOF by exception is annoying.)
 * Fortunatelly, U+FFFF is guaranteed not to be assigned
 * for any character.
 * Note distinction from EOF token type!
 */
var EOF_CHAR = String.fromCharCode(0xFFFF);

function TokenStream( parser, sourceString, lineno )
{
    this.parser = parser;
    this.sourceString = String(sourceString);
    this.sourceEnd    = this.sourceString.length;
    this.sourceCursor = 0;

    // stuff other than whitespace since start of line
    this.dirtyLine = false;

    this.string = "";

    this.stringBuffer = [];
    this.ungetBuffer  = [];

    this.hitEOF = false;

    this.lineStart   = 0;
    this.lineno      = Number(lineno) || 1;
    this.lineEndChar = undefined;

    // for xml tokenizer
    this.xmlIsAttribute   = false;
    this.xmlIsTagContent  = false;
    this.xmlOpenTagsCount = 0;
}

var proto = TokenStream.prototype;

/* This function uses the cached op, string and number fields in
 * TokenStream; if getToken has been called since the passed token
 * was scanned, the op or string printed may be incorrect.
 */
proto.tokenToString = function ( token )
{
    if (Token.printTrees) {
        var name = Token.name(token);

        switch ( token ) {
        case Token.STRING:
        case Token.REGEXP:
        case Token.NAME:
            return name + " `" + this.string + "'";

        case Token.NUMBER:
            return "NUMBER " + this.number;
        }

        return name;
    }
    return "";
};

function isKeyword ( s )
{
    return Token.EOF != stringToKeyword(s);
}

var strIdMap = {
    "break"         : Token.BREAK,
    "case"          : Token.CASE,
    "catch"         : Token.CATCH,
    "continue"      : Token.CONTINUE,
    "default"       : Token.DEFAULT,
    "delete"        : Token.DELPROP,
    "do"            : Token.DO,
    "else"          : Token.ELSE,
    "export"        : Token.EXPORT,
    "false"         : Token.FALSE,
    "finally"       : Token.FINALLY,
    "for"           : Token.FOR,
    "function"      : Token.FUNCTION,
    "if"            : Token.IF,
    "in"            : Token.IN,
    "instanceof"    : Token.INSTANCEOF,
    "new"           : Token.NEW,
    "null"          : Token.NULL,
    "return"        : Token.RETURN,
    "switch"        : Token.SWITCH,
    "this"          : Token.THIS,
    "throw"         : Token.THROW,
    "true"          : Token.TRUE,
    "try"           : Token.TRY,
    "typeof"        : Token.TYPEOF,
    "var"           : Token.VAR,
    "void"          : Token.VOID,
    "while"         : Token.WHILE,
    "with"          : Token.WITH,
    // Future Reserved Words
    "abstract"      : Token.RESERVED,
    "boolean"       : Token.RESERVED,
    "byte"          : Token.RESERVED,
    "char"          : Token.RESERVED,
    "class"         : Token.RESERVED,
    "const"         : Token.RESERVED,
    "debugger"      : Token.RESERVED,
    "double"        : Token.RESERVED,
    "enum"          : Token.RESERVED,
    "extends"       : Token.RESERVED,
    "final"         : Token.RESERVED,
    "float"         : Token.RESERVED,
    "goto"          : Token.RESERVED,
    "implements"    : Token.RESERVED,
    "import"        : Token.IMPORT,
    "int"           : Token.RESERVED,
    "interface"     : Token.RESERVED,
    "long"          : Token.RESERVED,
    "native"        : Token.RESERVED,
    "package"       : Token.RESERVED,
    "private"       : Token.RESERVED,
    "protected"     : Token.RESERVED,
    "public"        : Token.RESERVED,
    "short"         : Token.RESERVED,
    "static"        : Token.RESERVED,
    "super"         : Token.RESERVED,
    "synchronized"  : Token.RESERVED,
    "throws"        : Token.RESERVED,
    "transient"     : Token.RESERVED,
    "volatile"      : Token.RESERVED
};

function stringToKeyword ( name )
{
    return strIdMap.hasOwnProperty(name) ? strIdMap[name] : Token.EOF;
}

proto.getLineno = function ( ) { return this.lineno; };

proto.getString = function ( ) { return this.string; };

proto.eof = function ( ) { return this.hitEOF; };

proto.getToken = function ( )
{
    var c;

retry:
    for (;;) {
        // Eat whitespace, possibly sensitive to newlines.
        for (;;) {
            c = this.getChar();
            if ( c === EOF_CHAR ) {
                return Token.EOF;
            } else if ( c === '\n' ) {
                this.dirtyLine = false;
                return Token.EOL;
            } else if ( !isSpace(c) ) {
                if ( c !== '-' ) {
                    this.dirtyLine = true;
                }
                break;
            }
        }

        // identifier/keyword/instanceof?
        // watch out for starting with a <backslash>
        var identifierStart      = false;
        var isUnicodeEscapeStart = false;
        if ( c === '\\' ) {
            c = this.getChar();
            if ( c === 'u' ) {
                identifierStart      = true;
                isUnicodeEscapeStart = true;
                this.stringBuffer    = ["\\u"];
            } else {
                identifierStart = false;
                this.ungetChar(c);
                c = '\\';
            }
        } else if ( isIdentifierStart(c) ) {
            identifierStart   = true;
            this.stringBuffer = [c];
        }

        if ( identifierStart ) {
            var containsEscape = isUnicodeEscapeStart;
            for (;;) {
                if ( isUnicodeEscapeStart ) {
                    // strictly speaking we should probably push-back
                    // all the bad characters if the <backslash>uXXXX
                    // sequence is malformed. But since there isn't a
                    // correct context(is there?) for a bad Unicode
                    // escape sequence in an identifier, we can report
                    // an error here.
                    for ( var i=0;  i != 4;  ++i ) {
                        c = this.getChar();
                        if ( isHexDigit(c) ) {
                            this.addToString(c);
                        } else {
                            this.parser.addError("msg.invalid.escape");
                            return Token.ERROR;
                        }
                    }
                    isUnicodeEscapeStart = false;
                } else {
                    c = this.getChar();
                    if (c == '\\') {
                        c = this.getChar();
                        if (c == 'u') {
                            this.addToString("\\u");
                            isUnicodeEscapeStart = true;
                            containsEscape       = true;
                        } else {
                            this.parser.addError("msg.illegal.character");
                            return Token.ERROR;
                        }
                    } else {
                        if ( !isIdentifierPart(c) ) break;
                        this.addToString(c);
                    }
                }
            }
            this.ungetChar(c);

            var str = this.getStringFromBuffer();
            if ( !containsEscape ) {
                // OPT we shouldn't have to make a string to
                // check if it's a keyword.

                // Return the corresponding token if it's a keyword
                var result = stringToKeyword(str);
                if ( result != Token.EOF ) return result;
            }
            this.string = str;
            return Token.NAME;
        }

        // is it a number?
        if ( isDigit(c)  ||  (c==='.' && isDigit(this.peekChar())) ) {
            this.stringBuffer = [];
            var base = 10;

            if ( c === '0' ) {
                this.addToString('0');
                c = this.getChar();
                if ( c === 'x' || c === 'X' ) {
                    this.addToString(c);
                    base = 16;
                    c = this.getChar();
                } else if ( isDigit(c) ) {
                    base = 8;
                }
            }

            if ( base === 16 ) {
                while ( isHexDigit(c) ) {
                    this.addToString(c);
                    c = this.getChar();
                }
            } else {
                while ( isDigit(c) ) {
                    /*
                     * We permit 08 and 09 as decimal numbers, which
                     * makes our behavior a superset of the ECMA
                     * numeric grammar.  We might not always be so
                     * permissive, so we warn about it.
                     */
                    if ( base === 8  &&  (c==='8' || c==='9') ) {
                        this.parser.addWarning("msg.bad.octal.literal", c == '8' ? "8" : "9");
                        base = 10;
                    }
                    this.addToString(c);
                    c = this.getChar();
                }
            }

            if ( base === 10 ) {
                if ( c === '.' ) {
                    do {
                        this.addToString(c);
                        c = this.getChar();
                    } while ( isDigit(c) );
                }
                if ( c === 'e' || c === 'E' ) {
                    this.addToString(c);
                    c = this.getChar();
                    if ( c === '+' || c === '-' ) {
                        this.addToString(c);
                        c = this.getChar();
                    }
                    if ( !isDigit(c) ) {
                        this.parser.addError("msg.missing.exponent");
                        return Token.ERROR;
                    }
                    do {
                        this.addToString(c);
                        c = this.getChar();
                    } while ( isDigit(c) );
                }
            }
            this.ungetChar(c);

            this.string = this.getStringFromBuffer();
            return Token.NUMBER;
        }

        // is it a string?
        if ( c === '"' || c === "'" ) {
            var quoteChar = c;
            this.stringBuffer = [c];
            c = this.getChar();
            while ( c !== quoteChar ) {
                if ( c === '\n' || c === EOF_CHAR ) {
                    this.ungetChar(c);
                    this.parser.addError("msg.unterminated.string.lit");
                    return Token.ERROR;
                }
                if ( c === '\\' ) {
                    this.addToString('\\');
                    c = this.getChar();
                    if ( c === '\n' ) {
                        // Remove line terminator after escape to follow
                        // SpiderMonkey and C/C++
                        // But, issue warning since ECMA262-3 does not allow that.
                        this.parser.addWarning("msg.unsafe.string.lit");
                    } else {
                        this.addToString(c);
                    }
                } else {
                    this.addToString(c);
                }
                c = this.getChar();
            }
            this.addToString(quoteChar);
            this.string = this.getStringFromBuffer();
            return Token.STRING;
        }

        switch ( c.charCodeAt(0) ) {
        case 0x3B:  // ';'
            return Token.SEMI;

        case 0x5B:  // '['
            return Token.LB;

        case 0x5D:  // ']'
            return Token.RB;

        case 0x7B:  // '{'
            return Token.LC;

        case 0x7D:  // '}'
            return Token.RC;

        case 0x28:  // '('
            return Token.LP;

        case 0x29:  // ')'
            return Token.RP;

        case 0x2C:  // ','
            return Token.COMMA;

        case 0x3F:  // '?'
            return Token.HOOK;

        case 0x40:  // '@'
            return Token.XMLATTR;

        case 0x3A:  // ':'
            if ( this.matchChar(':') ) {
                return Token.COLONCOLON;
            } else {
                return Token.COLON;
            }

        case 0x2E:  // '.'
            if ( this.matchChar('.') ) {
                return Token.DOTDOT;
            } else if ( this.matchChar('(') ) {
                return Token.DOTQUERY;
            } else {
                return Token.DOT;
            }

        case 0x7C:  // '|'
            if ( this.matchChar('|') ) {
                return Token.OR;
            } else if ( this.matchChar('=') ) {
                return Token.ASSIGN_BITOR;
            } else {
                return Token.BITOR;
            }

        case 0x5E:  // '^'
            if ( this.matchChar('=') ) {
                return Token.ASSIGN_BITXOR;
            } else {
                return Token.BITXOR;
            }

        case 0x26:  // '&'
            if ( this.matchChar('&') ) {
                return Token.AND;
            } else if ( this.matchChar('=') ) {
                return Token.ASSIGN_BITAND;
            } else {
                return Token.BITAND;
            }

        case 0x3D:  // '='
            if ( this.matchChar('=') ) {
                if ( this.matchChar('=') ) {
                    return Token.SHEQ;
                } else {
                    return Token.EQ;
                }
            } else {
                return Token.ASSIGN;
            }

        case 0x21:  // '!'
            if ( this.matchChar('=') ) {
                if ( this.matchChar('=') ) {
                    return Token.SHNE;
                } else {
                    return Token.NE;
                }
            } else {
                return Token.NOT;
            }

        case 0x3C:  // '<'
            /* NB:treat HTML begin-comment as comment-till-eol */
            if ( this.matchChar('!') ) {
                if ( this.matchChar('-') ) {
                    if ( this.matchChar('-') ) {
                        this.skipLine();
                        continue retry;
                    }
                    this.ungetChar('-');
                }
                this.ungetChar('!');
            }
            if ( this.matchChar('<') ) {
                if ( this.matchChar('=') ) {
                    return Token.ASSIGN_LSH;
                } else {
                    return Token.LSH;
                }
            } else {
                if ( this.matchChar('=') ) {
                    return Token.LE;
                } else {
                    return Token.LT;
                }
            }

        case 0x3E:  // '>'
            if ( this.matchChar('>') ) {
                if ( this.matchChar('>') ) {
                    if ( this.matchChar('=') ) {
                        return Token.ASSIGN_URSH;
                    } else {
                        return Token.URSH;
                    }
                } else {
                    if ( this.matchChar('=') ) {
                        return Token.ASSIGN_RSH;
                    } else {
                        return Token.RSH;
                    }
                }
            } else {
                if ( this.matchChar('=') ) {
                    return Token.GE;
                } else {
                    return Token.GT;
                }
            }

        case 0x2A:  // '*'
            if ( this.matchChar('=') ) {
                return Token.ASSIGN_MUL;
            } else {
                return Token.MUL;
            }

        case 0x2F:  // '/'
            // is it a // comment?
            if ( this.matchChar('/') ) {
                this.skipLine();
                continue retry;
            } else if ( this.matchChar('*') ) {
                for (;;) {
                    c = this.getChar();
                    if ( c === EOF_CHAR ) {
                        this.parser.addError("msg.unterminated.comment");
                        return Token.ERROR;
                    } else if ( c === '*' ) {
                        c = this.getChar();
                        if ( c === '/' ) {
                            continue retry;
                        }
                    }
                }
            } else if ( this.matchChar('=') ) {
                return Token.ASSIGN_DIV;
            } else {
                return Token.DIV;
            }

        case 0x25:  // '%'
            if ( this.matchChar('=') ) {
                return Token.ASSIGN_MOD;
            } else {
                return Token.MOD;
            }

        case 0x7E:  // '~'
            return Token.BITNOT;

        case 0x2B:  // '+'
            if ( this.matchChar('=') ) {
                return Token.ASSIGN_ADD;
            } else if ( this.matchChar('+') ) {
                return Token.INC;
            } else {
                return Token.ADD;
            }

        case 0x2D:  // '-'
            if ( this.matchChar('=') ) {
                c = Token.ASSIGN_SUB;
            } else if ( this.matchChar('-') ) {
                if ( !this.dirtyLine ) {
                    // treat HTML end-comment after possible whitespace
                    // after line start as comment-untill-eol
                    if ( this.matchChar('>')) {
                        this.skipLine();
                        continue retry;
                    }
                }
                c = Token.DEC;
            } else {
                c = Token.SUB;
            }
            this.dirtyLine = true;
            return c;

        default:
            parser.addError("msg.illegal.character");
            return Token.ERROR;
        }
    }
};

/**
 * Parser calls the method when it gets / or /= in literal context.
 */
proto.readRegExp = function ( startToken )
{
    if ( startToken === Token.ASSIGN_DIV ) {
        // Miss-scanned /=
        this.stringBuffer = ["/="];
    } else if ( startToken === Token.DIV ) {
        this.stringBuffer = ["/"];
    } else {
        Kit.codeBug();
    }

    var c;
    while ( (c = this.getChar()) !== '/' ) {
        if ( c === '\n' || c === EOF_CHAR ) {
            this.ungetChar(c);
            throw this.parser.reportError("msg.unterminated.re.lit");
        }
        if ( c === '\\' ) {
            this.addToString(c);
            c = this.getChar();
        }
        this.addToString(c);
    }
    this.addToString("/");

    while ( isIdentifierPart(c = this.getChar()) ) {
        this.addToString(c);
    }
    this.ungetChar(c);

    this.string = this.getStringFromBuffer();
}

proto.isXMLAttribute = function ( )
{
    return this.xmlIsAttribute;
};

proto.getFirstXMLToken = function ( )
{
    this.xmlOpenTagsCount = 0;
    this.xmlIsAttribute   = false;
    this.xmlIsTagContent  = false;
    this.ungetChar('<');
    return this.getNextXMLToken();
};

proto.getNextXMLToken = function ( )
{
    this.stringBuffer = []; // remember the XML

    for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
        if ( this.xmlIsTagContent ) {
            switch ( c.charCodeAt(0) ) {
            case 0x3E:  // '>'
                this.addToString('>');
                this.xmlIsTagContent = false;
                this.xmlIsAttribute  = false;
                break;
            case 0x2F:  // '/'
                this.addToString('/');
                if ( this.matchChar('>') ) {
                    this.addToString('>');
                    this.xmlIsTagContent = false;
                    this.xmlOpenTagsCount--;
                }
                break;
            case 0x7B:  // '{'
                this.ungetChar('{');
                this.string = this.getStringFromBuffer();
                return Token.XML;
            case 0x27:  // "'"
            case 0x22:  // '"'
                this.addToString(c);
                if ( !this.readQuotedString(c) ) return Token.ERROR;
                break;
            case 0x3D:  // '='
                this.addToString('=');
                this.xmlIsAttribute = true;
                break;
            case 0x20:  // ' '
            case 0x09:  // '\t'
            // case 0x0D:  // '\r'  CR never comes here because of the implementation of getChar().
            case 0x0A:  // '\n'
                this.addToString(c);
                break;
            default:
                this.addToString(c);
                this.xmlIsAttribute = false;
                break;
            }

            if ( !this.xmlIsTagContent  &&  this.xmlOpenTagsCount === 0 ) {
                this.string = this.getStringFromBuffer();
                return Token.XMLEND;
            }
        } else {
            switch ( c.charCodeAt(0) ) {
            case 0x3C:  // '<'
                this.addToString('<');
                c = this.getChar();
                switch ( c.charCodeAt(0) ) {
                case 0x21:  // '!'
                    this.addToString('!');
                    c = this.getChar();
                    switch ( c.charCodeAt(0) ) {
                    case 0x2D:  // '-'
                        if ( this.getChar() === '-' ) {
                            this.addToString('--');
                            if ( !this.readXmlComment() ) return Token.ERROR;
                        } else {
                            this.parser.addError("msg.XML.bad.form");
                            return Token.ERROR;
                        }
                        break;
                    case 0x5B:  // '['
                        if ( this.getChar() === 'C' &&
                             this.getChar() === 'D' &&
                             this.getChar() === 'A' &&
                             this.getChar() === 'T' &&
                             this.getChar() === 'A' &&
                             this.getChar() === '['    )
                        {
                            this.addToString('[CDATA[');
                            if ( !this.readCDATA() ) return Token.ERROR;
                        } else {
                            this.parser.addError("msg.XML.bad.form");
                            return Token.ERROR;
                        }
                        break;
                    default:
                        this.ungetChar(c);
                        if( !this.readEntity() ) return Token.ERROR;
                        break;
                    }
                    break;
                case 0x3F:  // '?'
                    this.addToString('?');
                    if ( !this.readPI() ) return Token.ERROR;
                    break;
                case 0x2F:  // '/'
                    // End tag
                    this.addToString('/');
                    if ( this.xmlOpenTagsCount === 0 ) {
                        this.parser.addError("msg.XML.bad.form");
                        return Token.ERROR;
                    }
                    this.xmlIsTagContent = true;
                    this.xmlOpenTagsCount--;
                    break;
                default:
                    // Start tag
                    this.ungetChar(c);
                    this.xmlIsTagContent = true;
                    this.xmlOpenTagsCount++;
                    break;
                }
                break;
            case 0x7B:  // '{'
                this.ungetChar('{');
                this.string = this.getStringFromBuffer();
                return Token.XML;
            default:
                this.addToString(c);
                break;
            }
        }
    }

    this.parser.addError("msg.XML.bad.form");
    return Token.ERROR;
};

proto.readQuotedString = function ( quote )
{
    for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
        this.addToString(c);
        if ( c === quote ) return true;
    }
    parser.addError("msg.XML.bad.form");
    return false;
};

proto.readXmlComment = function ( )
{
    for ( var c=this.getChar();  c !== EOF_CHAR; ) {
        this.addToString(c);
        if ( c === '-'  &&  this.matchChar('-') ) {
            this.addToString('-');
            if ( this.matchChar('>') ) {
                this.addToString('>');
                return true;
            } else {
                // Strictly, XMLComment MUST NOT include the sequence "--".
                // So, if the program execution is here, the source is
                // syntactically wrong, according to ECMA367. However, we
                // allow the sequence here, so that our syntax is super-set
                // of the specification.
                c = '-';
                continue;
            }
        }
        c = this.getChar();
    }
    this.parser.addError("msg.XML.bad.form");
    return false;
};

proto.readCDATA = function ( )
{
    for ( var c=this.getChar();  c !== EOF_CHAR; ) {
        this.addToString(c);
        if ( c === ']'  &&  this.matchChar(']') ) {
            this.addToString(']');
            if ( this.matchChar('>') ) {
                this.addToString('>');
                return true;
            } else {
                c = ']';
                continue;
            }
        }
        c = this.getChar();
    }
    this.parser.addError("msg.XML.bad.form");
    return false;
};

proto.readEntity = function ( )
{
    var declTags = 1;
    for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
        this.addToString(c);
        switch ( c ) {
        case '<':
            declTags++;
            break;
        case '>':
            declTags--;
            if ( declTags === 0 ) return true;
            break;
        }
    }
    this.parser.addError("msg.XML.bad.form");
    return false;
};

proto.readPI = function ( )
{
    for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
        this.addToString(c);
        if ( c === '?'  &&  this.matchChar('>') ) {
            this.addToString('>');
            return true;
        }
    }
    this.parser.addError("msg.XML.bad.form");
    return false;
};

proto.getStringFromBuffer = function ( )
{
    return this.stringBuffer.join("");
};

proto.addToString = function ( /* variable arguments */ )
{
    this.stringBuffer.push.apply(this.stringBuffer, arguments);
};

proto.ungetChar = function ( c )
{
    // can not unread past across line boundary
    if ( this.ungetBuffer.length && this.ungetBuffer[this.ungetBuffer.length-1] == '\n') Kit.codeBug();
    this.ungetBuffer.push(c);
};

proto.matchChar = function ( test )
{
    var c = this.getChar();
    if ( c === test ) {
        return true;
    } else {
        this.ungetChar(c);
        return false;
    }
};

proto.peekChar = function ( )
{
    var c = this.getChar();
    this.ungetChar(c);
    return c;
};

proto.getChar = function ( )
{
    if ( this.ungetBuffer.length ) return this.ungetBuffer.pop();

    for ( ;; ) {
        if ( this.sourceCursor == this.sourceEnd ) {
            this.hitEOF = true;
            return EOF_CHAR;
        }
        var c = this.sourceString.charAt(this.sourceCursor++);

        if ( this.lineEndChar ) {
            if ( this.lineEndChar == '\r' && c == '\n') {
                this.lineEndChar = '\n';
                continue;
            }
            this.lineEndChar = undefined;
            this.lineStart   = this.sourceCursor - 1;
            this.lineno++;
        }

        if ( isLineTerminator(c) ) {
            this.lineEndChar = c;
            c = '\n';
        }
        if ( isFormatChar(c) ) {
            continue;
        }
        return c;
    }
};

proto.skipLine = function ( )
{
    // skip to end of line
    var c;
    while ((c=this.getChar()) != EOF_CHAR && c != '\n') { }
    this.ungetChar(c);
};

proto.getOffset = function ( )
{
    var n = this.sourceCursor - this.lineStart;
    if ( this.lineEndChar ) { --n; }
    return n;
};

proto.getLine = function ( )
{
    var lineEnd = this.sourceCursor;
    if ( this.lineEndChar ) {
        --lineEnd;
    } else {
        for (; lineEnd != this.sourceEnd; ++lineEnd) {
            var c = this.sourceString.charAt(lineEnd);
            if ( isLineTerminator(c) ) {
                break;
            }
        }
    }
    return this.sourceString.substring(this.lineStart, lineEnd);
};

            return {
                TokenStream: TokenStream
            };
        }();
    }
}.call(null) ) {
    this.Concurrent.Thread.Compiler.TokenStream = TokenStream;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Concurrent.Thread.Compiler.IntermediateLanguage || (typeof this.Concurrent.Thread.Compiler.IntermediateLanguage != 'object' && typeof this.Concurrent.Thread.Compiler.IntermediateLanguage != 'function') ) this.Concurrent.Thread.Compiler.IntermediateLanguage = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Function === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Function = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Block === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Block = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement = undefined;
    if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler.IntermediateLanguage ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler.IntermediateLanguage';

function Function ( name, params, vars, body, start ) {
    this.name   = name;    // Identifier | Null
    this.params = params;  // [Identifier]
    this.vars   = vars;    // [Identifier]
    this.body   = body;    // <Block>
    this.start  = start;   // Block
}

Function.prototype.toString = function ( ) {
    return  [ "function ", this.name, "( ", this.params.join(", "), " ) {\n",
              "  var ", this.vars.join(", "), ";\n",
              this.body.join("\n").replace(/^/mg, "  "),
              "\n}" ].join("");
};

var block_id = 0;

function Block ( scopes, body, target, exception ) {
    this.id        = "label" + block_id++;
    this.scopes    = scopes;     // [Expression]
    this.body      = body;       // <Statement>
    this.target    = target;     // Block | "return" | "throw"
    this.exception = exception;  // Block | "return" | "throw"
}

var proto = Block.prototype;

proto.toString = function ( ) {
    Kit.codeBug('"toString" is not implemented for ', this.constructor);
};

proto.appendStatement = function ( /* variable arguments */ ) {
    var args = arguments;
    if ( this.body.isNil() ) {
        this.body = cons(arguments[0], this.body);
        args = Array.prototype.slice.call(arguments, 1, arguments.length);
    } else {
        adder(this.body).apply(null, args);
    }
};

proto.prependStatement = function ( /* variable arguments */ ) {
    for ( var i=arguments.length-1;  i >= 0;  i-- ) {
        this.body = cons(arguments[i], this.body);
    }
};

function stringify ( b ) {
    if ( b instanceof Block ) {
        return b.id;
    } else {
        return '"' + b + '"';
    }
}

function GotoBlock ( scopes, body, arg, target, exception ) {
    Block.call(this, scopes, body, target, exception);
    this.arg = arg;
}

var proto = GotoBlock.prototype = new Block();

proto.constructor = GotoBlock;

proto.toString = function ( ) {
    return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
             this.body.join("\n").replace(/^/mg, "  "), "\n",
             "  goto ", this.arg, " -> ", stringify(this.target), "\n",
             "}" ].join("");
};

function CallBlock ( scopes, body, this_val, func, args, target, exception ) {
    Block.call(this, scopes, body, target, exception);
    this.this_val  = this_val;   // Expression
    this.func      = func;       // Expression
    this.args      = args;       // [Expression]
}

var proto = CallBlock.prototype = new Block();

proto.constructor = CallBlock;

proto.toString = function ( ) {
    return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
             this.body.join("\n").replace(/^/mg, "  "), "\n",
             "  call ", this.this_val, ".", this.func, "(", this.args.join(", "), ") -> ", stringify(this.target), "\n",
             "}" ].join("");
};

function NewBlock ( scopes, body, func, args, target, exception ) {
    Block.call(this, scopes, body, target, exception);
    this.func      = func;       // Expression
    this.args      = args;       // [Expression]
}

var proto = NewBlock.prototype = new Block();

proto.constructor = NewBlock;

proto.toString = function ( ) {
    return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
             this.body.join("\n").replace(/^/mg, "  "), "\n",
             "  new ", this.func, "(", this.args.join(", "), ") -> ", stringify(this.target), "\n",
             "}" ].join("");
};

function Statement ( ) {
    // This is kind of interface.
}

Statement.prototype.toString = function ( ) {
    Kit.codeBug('"toString" is not implemented for ', this.constructor);
};

function ExpStatement ( e ) {
    this.exp = e;  // Expression
}

var proto = ExpStatement.prototype = new Statement();

proto.constructor = ExpStatement;

proto.toString = function ( ) {
    return this.exp + ";";
};

function CondStatement ( c, t ) {
    this.cond   = c;  // Expression
    this.target = t;  // Block
}

var proto = CondStatement.prototype = new Statement();

proto.constructor = CondStatement;

proto.toString = function ( ) {
    return [ "if ", this.cond, " -> ", stringify(this.target), ";" ].join("");
};

function RecvStatement ( a ) {
    this.assignee = a;  // Identifier | DotAccessor | BracketAccessor
}

var proto = RecvStatement.prototype = new Statement();

proto.constructor = RecvStatement;

proto.toString = function ( ) {
    return [ "recv ", this.assignee, ";" ].join("");
};

function EnumStatement ( e, a ) {
    this.exp      = e;  // Expression
    this.assignee = a;  // Identifier | DotAccessor | BracketAccessor
}

var proto = EnumStatement.prototype = new Statement();

proto.constructor = EnumStatement;

proto.toString = function ( ) {
    return [ "enum ", this.assignee, " <- ", this.exp, ";" ].join("");
};

            return {
                Block: Block, RecvStatement: RecvStatement, GotoBlock: GotoBlock, Function: Function, NewBlock: NewBlock, ExpStatement: ExpStatement, CallBlock: CallBlock, EnumStatement: EnumStatement, Statement: Statement, CondStatement: CondStatement
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.IntermediateLanguage.Block = Block;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement = RecvStatement;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock = GotoBlock;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.Function = Function;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock = NewBlock;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement = ExpStatement;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock = CallBlock;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement = EnumStatement;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement = Statement;
    this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement = CondStatement;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.CssConvert === undefined ) this.Concurrent.Thread.Compiler.CssConvert = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var Css = "Concurrent.Thread.Compiler.CssConvert";

function CssConvert ( func ) {
    return func[Css]();
}

Statement.prototype[Css] = function ( ) {
    Kit.codeBug("unimplemented '" + Css + "' method for: " + this);
};

EmptyStatement.prototype[Css] = function ( ) {
    return this;
};

Block.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new Block(this.labels, head.cdr, this.lineno, this.source);
};

ExpStatement.prototype[Css] = function ( ) {
    return new ExpStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

VarStatement.prototype[Css] = function ( ) {
    var decls = [];
    for ( var i=0;  i < this.decls.length;  i++ ) {
        decls[i] = {
            id : this.decls[i].id,
            exp: this.decls[i].exp ? this.decls[i].exp[Css]() : null
        };
    }
    return new VarStatement(this.labels, decls, this.lineno, this.source);
};

IfStatement.prototype[Css] = function ( ) {
    return new IfStatement(this.labels, this.cond[Css](), this.body[Css](), this.lineno, this.source);
};

IfElseStatement.prototype[Css] = function ( ) {
    return new IfElseStatement(this.labels, this.cond[Css](), this.tbody[Css](), this.fbody[Css](), this.lineno, this.source);
};

DoWhileStatement.prototype[Css] = function ( ) {
    return new DoWhileStatement(this.labels, this.body[Css](), this.cond[Css](), this.lineno, this.source);
};

WhileStatement.prototype[Css] = function ( ) {
    return new WhileStatement(this.labels, this.cond[Css](), this.body[Css](), this.lineno, this.source);
};

ForStatement.prototype[Css] = function ( ) {
    return new ForStatement(
        this.labels,
        this.init ? this.init[Css]() : null,
        this.cond ? this.cond[Css]() : null,
        this.incr ? this.incr[Css]() : null,
        this.body[Css](),
        this.lineno,
        this.source
    );
};

ForVarStatement.prototype[Css] = function ( ) {
    var decls = [];
    for ( var i=0;  i < this.decls.length;  i++ ) {
        decls[i] = {
            id : this.decls[i].id,
            exp: this.decls[i].exp ? this.decls[i].exp[Css]() : null
        };
    }
    return new ForVarStatement(
        this.labels,
        decls,
        this.cond ? this.cond[Css]() : null,
        this.incr ? this.incr[Css]() : null,
        this.body[Css](),
        this.lineno,
        this.source
    );
};

ForInStatement.prototype[Css] = function ( ) {
    return new ForInStatement(this.labels, this.lhs[Css](), this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForInVarStatement.prototype[Css] = function ( ) {
    var decl = {
        id : this.decl.id,
        exp: this.decl.exp ? this.decl.exp[Css]() : null
    };
    return new ForInVarStatement(this.labels, decl, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForEachStatement.prototype[Css] = function ( ) {
    return new ForEachStatement(this.labels, this.lhs[Css](), this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForEachVarStatement.prototype[Css] = function ( ) {
    var decl = {
        id : this.decl.id,
        exp: this.decl.exp ? this.decl.exp[Css]() : null
    };
    return new ForEachVarStatement(this.labels, decl, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ContinueStatement.prototype[Css] = function ( ) {
    return this;
};

BreakStatement.prototype[Css] = function ( ) {
    return this;
};

ReturnStatement.prototype[Css] = function ( ) {
    if ( !this.exp ) return this;
    return new ReturnStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

WithStatement.prototype[Css] = function ( ) {
    return new WithStatement(this.labels, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

SwitchStatement.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.clauses;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new SwitchStatement(this.labels, this.exp[Css](), head.cdr, this.lineno, this.source);
};

CaseClause.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new CaseClause(this.exp[Css](), head.cdr, this.lineno, this.source);
};

DefaultClause.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new DefaultClause(head.cdr, this.lineno, this.source);
};

ThrowStatement.prototype[Css] = function ( ) {
    return new ThrowStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

TryCatchStatement.prototype[Css] = function ( ) {
    return new TryCatchStatement(this.labels, this.tryBlock[Css](), this.variable, this.catchBlock[Css](), this.lineno, this.source);
};

TryFinallyStatement.prototype[Css] = function ( ) {
    return new TryFinallyStatement(this.labels, this.tryBlock[Css](), this.finallyBlock[Css](), this.lineno, this.source);
};

TryCatchFinallyStatement.prototype[Css] = function ( ) {
    return new TryCatchFinallyStatement(this.labels, this.tryBlock[Css](), this.variable, this.catchBlock[Css](), this.finallyBlock[Css](), this.lineno, this.source);
};

TryCatchListStatement.prototype[Css] = function ( ) {
    if ( this.catchList.isNil() ) {  // no more catch-guard
        var block = this.tryBlock[Css]();
        block.labels = this.labels;
        return block;
    } else if ( this.catchList.car.cond ) {  // one or more qualified catch-guard
        var guard = this.catchList.car;
        return new TryCatchStatement(
            this.labels,
            this.tryBlock[Css](),
            guard.variable,
            new Block([], list(
                new IfElseStatement(
                    [],
                    guard.cond[Css](),
                    guard.block[Css](),
                    (new TryCatchListStatement(
                        [],
                        new Block([], list(new ThrowStatement([], guard.variable))),
                        this.catchList.cdr,
                        this.catchList.cdr.lineno, this.cdr.cdr.source
                    ))[Css](),
                    guard.lineno, guard.source
                )
            ))
        );
    } else {  // (only one) default catch-guard
        var guard = this.catchList.car;
        return new TryCatchStatement(this.labels, this.tryBlock[Css](), guard.variable, guard.block[Css](), this.lineno, this.source);
    }
};

TryCatchListFinallyStatement.prototype[Css] = function ( ) {
    return new TryFinallyStatement(
        this.labels,
        new Block([], list(
            (new TryCatchListStatement([],
                this.tryBlock,
                this.catchList,
                this.lineno,
                this.source
            ))[Css]()
        ), this.lineno, this.source),
        this.finallyBlock[Css](),
        this.lineno, this.source
    );
};

FunctionDeclaration.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new FunctionDeclaration(this.labels, this.name, this.params, head.cdr, this.lineno, this.source);
};

Expression.prototype[Css] = Statement.prototype[Css];

UnaryExpression.prototype[Css] = function ( ) {
    return new this.constructor( this.exp[Css]() );
};

BinaryExpression.prototype[Css] = function ( ) {
    return new this.constructor(this.left[Css](), this.right[Css]());
};

Literal.prototype[Css]        =
Identifier.prototype[Css]     =
ThisExpression.prototype[Css] =
Elision.prototype[Css]        = function ( ) {
    return this;
};

ArrayInitializer.prototype[Css] = function ( ) {
    var elems = [];
    for ( var i=0;  i < this.elems.length;  i++ ) {
        elems[i] = this.elems[i][Css]();
    }
    return new ArrayInitializer(elems);
};

ObjectInitializer.prototype[Css] = function ( ) {
    var pairs = [];
    for ( var i=0;  i < this.pairs.length;  i++ ) {
        pairs[i] = {prop:this.pairs[i].prop, exp:this.pairs[i].exp[Css]()};
    }
    return new ObjectInitializer(pairs);
};

FunctionExpression.prototype[Css] = function ( ) {
    var head = last = cons(null, nil());
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        last = last.cdr = cons(c.car[Css](), last.cdr);
    }
    return new FunctionExpression(this.name, this.params, head.cdr);
};

DotAccessor.prototype[Css] = function ( ) {
    return new DotAccessor(this.base[Css](), this.prop);
};

NewExpression.prototype[Css]  =
CallExpression.prototype[Css] = function ( ) {
    var args = [];
    for ( var i=0;  i < this.args.length;  i++ ) {
        args[i] = this.args[i][Css]();
    }
    return new this.constructor(this.func[Css](), args);
};

ConditionalExpression.prototype[Css] = function ( ) {
    return new ConditionalExpression(this.cond[Css](), this.texp[Css](), this.fexp[Css]());
};

            return {
                CssConvert: CssConvert
            };
        }();
    }
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CssConvert = CssConvert;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.Parser === undefined ) this.Concurrent.Thread.Compiler.Parser = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Data ) {
with ( Data.Error ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Mike Ang
 *   Igor Bukanov
 *   Yuh-Ruey Chen
 *   Ethan Hugg
 *   Terry Lucas
 *   Mike McCabe
 *   Milen Nankov
 *   Daisuke Maki
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * This file is based on the file Parser.java in Rhino 1.6R5.
 */

NAMESPACE = 'Concurrent.Thread.Compiler';

// TokenInformation flags : flaggedTokenBuffer stores them together
// with token type
var CLEAR_TI_MASK  = 0xFFFF;   // mask to clear token information bits
var TI_AFTER_EOL   = 1 << 16;  // first token of the source line
var TI_CHECK_LABEL = 1 << 17;  // indicates to check for label

// Exception to unwind
var ParserException = Exception.extend(
    function($super, message){ $super(message); },
    { name: NAMESPACE + ".ParserException" }
);

// Exception to return statement-label
function LabelException ( label ) {
    this.label = label;  // Identifier
}

// default error reporter
var defaultReporter = new ErrorReporter();
defaultReporter.error = function ( message, line, lineSource, lineOffset ) {
    throw new SyntaxError("(" + line + ", " + lineOffset + "): " + message + "\nline: " + lineSource);
};

function Parser ( errorReporter )
{
    this.errorReporter       = errorReporter instanceof ErrorReporter
                                 ?  errorReporter  :  defaultReporter;
    this.ts                  = undefined;  // TokenStream
    this.source              = undefined;  // String       # file-name, URL, ...etc
    this.flaggedTokenBuffer  = null;       // Stack
    this.syntaxErrorCount    = 0;
    this.nestingOfFunction   = 0;
    // The following are per function variables and should be saved/restored
    // during function parsing.
    this.nestingOfLoop   = 0;
    this.nestingOfSwitch = 0;
    this.allLabelSet     = null;  // contains all labels in current scope
    this.loopLabelSet    = null;  // contains only labels qualifying IterationStatement in current scope
}

var proto = Parser.prototype;

proto.getMessage = function ( messageId  /* optional args */ )
{
    //!! fake implementation
    return messageId;
};

proto.addWarning = function ( messageId  /* optional args */ )
{
    this.errorReporter.warning(this.getMessage.apply(this, arguments),
                               this.ts.getLineno()                   ,
                               this.ts.getLine()                     ,
                               this.ts.getOffset()                   );
};

proto.addError = function ( messageId  /* optional args */ )
{
    ++this.syntaxErrorCount;
    this.errorReporter.error(this.getMessage.apply(this, arguments),
                             this.ts.getLineno()                   ,
                             this.ts.getLine()                     ,
                             this.ts.getOffset()                   );
};

proto.reportError = function ( messageId  /* optional args */ )
{
    this.addError.apply(this, arguments);
    // Throw a ParserException exception to unwind the recursive descent
    // parse.
    throw new ParserException();
};

proto.peekToken = function ( )
{
    var tt;
    if ( this.flaggedTokenBuffer.isEmpty() ) {
        tt = this.ts.getToken();
        if ( tt === Token.EOL ) {
            do {
                tt = this.ts.getToken();
            } while ( tt === Token.EOL );
            tt |= TI_AFTER_EOL;
        }
        this.flaggedTokenBuffer.push(tt);
    } else {
        tt = this.flaggedTokenBuffer.peek();
    }
    return tt & CLEAR_TI_MASK;
};

proto.peekFlaggedToken = function ( )
{
    this.peekToken();
    return this.flaggedTokenBuffer.peek();
};

proto.consumeToken = function ( )
{
    this.flaggedTokenBuffer.pop();
};

proto.nextToken = function ( )
{
    var tt = this.peekToken();
    this.consumeToken();
    return tt;
};

proto.nextFlaggedToken = function ( )
{
    this.peekToken();
    var ttFlagged = this.flaggedTokenBuffer.peek();
    this.consumeToken();
    return ttFlagged;
};

proto.matchToken = function ( toMatch )
{
    if ( this.peekToken() !== toMatch ) return false;
    this.consumeToken();
    return true;
};

proto.peekTokenOrEOL = function ( )
{
    var tt = this.peekToken();
    // Check for last peeked token flags
    if ( this.flaggedTokenBuffer.peek() & TI_AFTER_EOL ) return Token.EOL;
    return tt;
};

// Since we need to backtrack to properly parse "default xml namespace"
// in switch-statement.
proto.ungetToken = function ( token )
{
    this.flaggedTokenBuffer.push(token);
};

proto.setCheckForLabel = function ( )
{
    var tt = this.flaggedTokenBuffer.pop();
    if ( (tt & CLEAR_TI_MASK) !== Token.NAME ) throw Kit.codeBug();
    this.flaggedTokenBuffer.push(tt | TI_CHECK_LABEL);
};

proto.mustMatchToken = function ( toMatch, messageId  /* optional args */ )
{
    if ( !this.matchToken(toMatch) ) {
        var args = [];
        for ( var i=1;  i < arguments.length;  i++ ) args.push(arguments[i]);
        this.reportError.apply(this, args);
    }
};

proto.eof = function ( )
{
    return this.ts.eof();
};

proto.insideFunction = function ( )
{
    return this.nestingOfFunction !== 0;
};

proto.insideLoop = function ( )
{
    return this.nestingOfLoop !== 0;
};

proto.enterLoop = function ( labels )
{
    for ( var i=0;  i < labels.length;  i++ ) this.loopLabelSet.add(labels[i]);
    this.nestingOfLoop++;
};

proto.exitLoop = function ( labels )
{
    for ( var i=0;  i < labels.length;  i++ ) this.loopLabelSet.remove(labels[i]);
    this.nestingOfLoop--;
};

proto.parse = function ( sourceString, lineno, source )
{
    this.ts     = new TokenStream(this, sourceString, lineno);
    this.source = source;  // optional
    this.flaggedTokenBuffer = new Stack();
    this.syntaxErrorCount   = 0;
    this.nestingOfFunction  = 0;
    this.nestingOfLoop      = 0;
    this.nestingOfSwitch    = 0;
    this.allLabelSet        = new IdentifierSet();
    this.loopLabelSet       = new IdentifierSet();

    try {
        var body = this.statements();
        this.mustMatchToken(Token.EOF, "msg.syntax");
    } catch ( e ) {
        if ( e instanceof ParserException ) {
            // Ignore it.
        } else {
            // Maybe stack overflow.
            //!!fake implementation
            throw e;
        }
    }

    if ( this.syntaxErrorCount ) {
        var msg = "msg.got.syntax.errors";
        this.addError(msg);
        throw new SyntaxError(this.getMessage("msg.got.syntax.errors"));
    }

    this.ts = null; // It helps GC
    return body;
};

proto.statements = function ( )
{
    var head, cell;
    cell = head = cons(null, nil());
    bodyLoop: for (;;) {
        var n;
        switch ( this.peekToken() ) {
          case Token.ERROR:
          case Token.EOF:
          case Token.RC:
            break bodyLoop;
          case Token.FUNCTION:  // save the stack
            this.consumeToken();
            n = this.functionDecl([]);
            break;
          default:
            n = this.statement();
            break;
        }
        cell = cell.cdr = cons(n, cell.cdr);
    }
    return head.cdr;
};

proto.functionDecl = function ( labels )
{
    var baseLineno = this.ts.getLineno();  // line number where source starts
    this.mustMatchToken(Token.NAME, "msg.no.func.name");
    var name   = new Identifier(this.ts.getString());
    var params = this.parameterList();
    var body   = this.functionBody();
    return new FunctionDeclaration(labels, name, params, body, baseLineno, this.source);
};

proto.functionExpr = function ( )
{
    var name = null;
    if ( this.matchToken(Token.NAME) ) name = new Identifier(this.ts.getString());
    var params = this.parameterList();
    var body   = this.functionBody();
    return new FunctionExpression(name, params, body);
};

proto.parameterList = function ( )
{
    this.mustMatchToken(Token.LP, "msg.no.paren.parms");
    if ( this.matchToken(Token.RP) ) return [];
    var params = [];
    var exists = new IdentifierSet();
    do {
        this.mustMatchToken(Token.NAME, "msg.no.parm");
        var p = new Identifier(this.ts.getString());
        if ( exists.contains(p) ) this.addWarning("msg.dup.parms", s);
        params.push(p);
        exists.add(p);
    } while ( this.matchToken(Token.COMMA) );
    this.mustMatchToken(Token.RP, "msg.no.paren.after.parms");
    return params;
};

proto.functionBody = function ( )
{
    this.mustMatchToken(Token.LC, "msg.no.brace.body");

    var saveAllLabel  = this.allLabelSet;
    var saveLoopLabel = this.loopLabelSet;
    var saveLoop      = this.nestingOfLoop;
    var saveSwitch    = this.nestingOfSwitch;
    this.allLabelSet  = new IdentifierSet();
    this.loopLabelSet = new IdentifierSet();
    this.nestingOfLoop   = 0;
    this.nestingOfSwitch = 0;
    this.nestingOfFunction++;
    try {
        var body = this.statements();
    } catch ( e ) {
        if ( e instanceof ParserException ) {
            // Ignore it
        } else {
            throw e;
        }
    } finally {
        this.allLabelSet     = saveAllLabel;
        this.loopLabelSet    = saveLoopLabel;
        this.nestingOfLoop   = saveLoop;
        this.nestingOfSwitch = saveSwitch;
        this.nestingOfFunction--;
    }

    this.mustMatchToken(Token.RC, "msg.no.brace.after.body");
    return body;
};

proto.statement = function ( )
{
    try {
        var n = this.statementHelper([]);
        if ( n != null ) return n;
    } catch ( e ) {
        if ( e instanceof ParserException ) {
            // Ignore it.
        } else {
            throw e;
        }
    }

    // skip to end of statement
    guessingStatementEnd: for (;;) {
        var tt = this.peekTokenOrEOL();
        this.consumeToken();
        switch ( tt ) {
          case Token.ERROR:
          case Token.EOF:
          case Token.EOL:
          case Token.SEMI:
            break guessingStatementEnd;
        }
    }
    return null;
};

proto.statementHelper = function ( labels )
{
    var statement = null;
    switch ( this.peekToken() ) {
      case Token.IF: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        var cond   = this.condition();
        var tstat  = this.statement();
        if ( this.matchToken(Token.ELSE) ) {
            return new IfElseStatement(labels, cond, tstat, this.statement(), lineno, this.source);
        } else {
            return new IfStatement(labels, cond, tstat, lineno, this.source);
        }
      }

      case Token.SWITCH: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        this.mustMatchToken(Token.LP, "msg.no.paren.switch");
        var exp = this.expr(false);
        this.mustMatchToken(Token.RP, "msg.no.paren.after.switch");
        this.mustMatchToken(Token.LC, "msg.no.brace.switch");
        var switchStatement = new SwitchStatement(labels, exp, nil(), lineno, this.source);
        var clauses = cons(nil(), nil());
        var last = clauses;
        this.nestingOfSwitch++;
        try {
            var hasDefault = false;
            switchLoop: for (;;) {
                var lineno = this.ts.getLineno();
                var caseExpression;
                switch ( this.nextToken() ) {
                  case Token.RC:
                    break switchLoop;
                  case Token.CASE:
                    caseExpression = this.expr(false);
                    this.mustMatchToken(Token.COLON, "msg.no.colon.case");
                    break;
                  case Token.DEFAULT:
                    if ( hasDefault ) this.reportError("msg.double.switch.default");
                    hasDefault     = true;
                    caseExpression = null;
                    this.mustMatchToken(Token.COLON, "msg.no.colon.case");
                    break;
                  default:
                    this.reportError("msg.bad.switch");
                    break switchLoop;
                }
                var c = caseExpression
                          ?  new CaseClause(caseExpression, this.statementsInSwitch(), lineno, this.source)
                          :  new DefaultClause(this.statementsInSwitch(), lineno, this.source);
                last = last.cdr = cons(c, last.cdr);
            }
        } finally {
            this.nestingOfSwitch--;
        }
        switchStatement.clauses = clauses.cdr;
        return switchStatement;
      }

      case Token.WHILE: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        this.enterLoop(labels);
        try {
            return new WhileStatement(labels, this.condition(), this.statement(), lineno, this.source);
        } finally {
            this.exitLoop(labels);
        }
      }

      case Token.DO: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        this.enterLoop(labels);
        try {
            var body = this.statement();
        } finally {
            this.exitLoop(labels);
        }
        this.mustMatchToken(Token.WHILE, "msg.no.while.do");
        var cond = this.condition();
        // Always auto-insert semicon to follow SpiderMonkey:
        // It is required by EMAScript but is ignored by the rest of
        // world, see bug 238945
        this.matchToken(Token.SEMI);
        return new DoWhileStatement(labels, body, cond, lineno, this.source);
      }

      case Token.FOR: {
        this.consumeToken();
        var lineno = this.ts.getLineno();

        var init;  // init is also foo in 'foo in Object'
        var cond;  // cond is also object in 'foo in Object'
        var incr = null;
        var body;

        var isForEach = false;
        var isForIn   = false;
        var isVar     = false;

        // See if this is a for each () instead of just a for ()
        if ( this.matchToken(Token.NAME) ) {
            if ( this.ts.getString() === "each" ) {
                isForEach = true;
            } else {
                this.reportError("msg.no.paren.for");
            }
        }

        this.mustMatchToken(Token.LP, "msg.no.paren.for");

        var tt = this.peekToken();
        if ( tt === Token.SEMI ) {
            init = null;
        } else {
            if ( tt === Token.VAR ) {
                // set init to a var list or initial
                this.consumeToken();    // consume the 'var' token
                init  = this.variables(true);
                isVar = true;
            }
            else {
                init = this.expr(true);
            }
        }

        if ( this.matchToken(Token.IN) ) {
            isForIn = true;
            // 'cond' is the object over which we're iterating
            cond = this.expr(false);
        } else {  // ordinary for loop
            this.mustMatchToken(Token.SEMI, "msg.no.semi.for");
            if ( this.peekToken() === Token.SEMI ) {
                // no loop condition
                cond = null;
            } else {
                cond = this.expr(false);
            }

            this.mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
            if ( this.peekToken() === Token.RP ) {
                incr = null;
            } else {
                incr = this.expr(false);
            }
        }

        this.mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");

        this.enterLoop(labels);
        try {
            body = this.statement();
        } finally {
            this.exitLoop(labels);
        }

        if ( !isForIn ) {
            // Although SpiderMonkey doesn't allow "for each ( ...; ...; ... )",
            // Rhino1.6R5 allowed it. We follow Rhino's position here.
            if ( isVar ) return new ForVarStatement(labels, init, cond, incr, body, lineno, this.source);
            else         return new ForStatement(labels, init, cond, incr, body, lineno, this.source);
        } else {
            if ( isVar ) {
                // Check if init (var declarations) contains only one.
                if ( init.length != 1 ) this.reportError("msg.mult.index");
                if ( isForEach ) return new ForEachVarStatement(labels, init[0], cond, body, lineno, this.source);
                else             return new ForInVarStatement(labels, init[0], cond, body, lineno, this.source);
            } else {
                // Check if init (an expression left-hand-side of "in") has lvalue.
                if ( !init.hasLvalue() ) this.reportError("msg.bad.for.in.lhs");
                if ( isForEach ) return new ForEachStatement(labels, init, cond, body, lineno, this.source);
                else             return new ForInStatement(labels, init, cond, body, lineno, this.source);
            }
        }
      }

      case Token.TRY: {
        this.consumeToken();
        var lineno = this.ts.getLineno();

        // Although ECMA262-3 requires a block here, Rhino1.6R5 allows any kind of statement.
        // We follow Rhino's style, but issue warning when a statement is not a block.
        var tryBlock = this.statement();
        if ( !(tryBlock instanceof Block) ) {
            this.addWarning("msg.no.brace.tryblock");
            tryBlock = new Block([], cons(tryBlock, nil()), tryBlock.lineno, tryBlock.source);
        }

        var catchList;
        var cell = catchList = cons(null, nil());
        var sawDefaultCatch = false;
        var peek = this.peekToken();
        if ( peek === Token.CATCH ) {
            while ( this.matchToken(Token.CATCH) ) {
                if ( sawDefaultCatch ) this.reportError("msg.catch.unreachable");
                var line = this.ts.getLineno();
                this.mustMatchToken(Token.LP, "msg.no.paren.catch");
                this.mustMatchToken(Token.NAME, "msg.bad.catchcond");
                var variable = new Identifier(this.ts.getString());

                var cond = null;
                if ( this.matchToken(Token.IF) ) {
                    cond = this.expr(false);
                } else {
                    sawDefaultCatch = true;
                }

                this.mustMatchToken(Token.RP, "msg.bad.catchcond");
                this.mustMatchToken(Token.LC, "msg.no.brace.catchblock");
                var block = new Block([], this.statements(), line, this.source);
                this.mustMatchToken(Token.RC, "msg.no.brace.after.body");

                var clause = new CatchGuard(variable, cond, block, line, this.source);
                cell = cell.cdr = cons(clause, cell.cdr);
            }
        } else if ( peek !== Token.FINALLY ) {
            this.mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
        }
        catchList = catchList.cdr;

        var finallyBlock = null;
        if ( this.matchToken(Token.FINALLY) ) {
            // Rhino also allows any kind of statement here.
            finallyBlock = this.statement();
            if ( !(finallyBlock instanceof Block) ) {
                this.addWarning("msg.no.brace.finallyblock");
                finallyBlock = new Block([], cons(finallyBlock, nil()), finallyBlock.lineno, finallyBlock.source);
            }
        }

        return finallyBlock
                 ? new TryCatchListFinallyStatement(labels, tryBlock, catchList, finallyBlock, lineno, this.source)
                 : new TryCatchListStatement(labels, tryBlock, catchList, lineno, this.source);
      }

      case Token.THROW: {
        this.consumeToken();
        if ( this.peekTokenOrEOL() === Token.EOL ) {
            // ECMAScript does not allow new lines before throw expression,
            // see bug 256617
            this.reportError("msg.bad.throw.eol");
        }

        var lineno = this.ts.getLineno();
        statement = new ThrowStatement(labels, this.expr(false), lineno, this.source);
        break;
      }

      case Token.BREAK: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        var target = this.matchJumpLabelName(Token.BREAK);
        if ( target == null ) {
            if ( !this.nestingOfLoop && !this.nestingOfSwitch ) this.reportError("msg.bad.break");
        }
        statement = new BreakStatement(labels, target, lineno, this.source);
        break;
      }

      case Token.CONTINUE: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        var target = this.matchJumpLabelName(Token.CONTINUE);
        if ( target == null ) {
            if ( !this.nestingOfLoop ) reportError("msg.continue.outside");
        }
        statement = new ContinueStatement(labels, target, lineno, this.source);
        break;
      }

      case Token.WITH: {
        this.consumeToken();
        var lineno = this.ts.getLineno();
        this.mustMatchToken(Token.LP, "msg.no.paren.with");
        var exp = this.expr(false);
        this.mustMatchToken(Token.RP, "msg.no.paren.after.with");
        var body = this.statement();
        return new WithStatement(labels, exp, body, lineno, this.source);
      }

      case Token.VAR: {
        this.consumeToken();
        statement = new VarStatement(labels, this.variables(false), lineno, this.source);
        break;
      }

      case Token.RETURN: {
        if ( !this.insideFunction() ) this.reportError("msg.bad.return");
        this.consumeToken();
        var lineno = this.ts.getLineno();
        var exp;
        /* This is ugly, but we don't want to require a semicolon. */
        switch ( this.peekTokenOrEOL() ) {
          case Token.SEMI:
          case Token.RC:
          case Token.EOF:
          case Token.EOL:
          case Token.ERROR:
            exp = null;
            break;
          default:
            exp = this.expr(false);
        }
        statement = new ReturnStatement(labels, exp, lineno, this.source);
        break;
      }

      case Token.LC:
        this.consumeToken();
        var block = new Block(labels, this.statements(), lineno, this.source);
        this.mustMatchToken(Token.RC, "msg.no.brace.block");
        return block;

      case Token.ERROR:
        // Fall thru, to have a node for error recovery to work on
      case Token.SEMI:
        this.consumeToken();
        return new EmptyStatement(labels, lineno, this.source);

      case Token.FUNCTION: {
        this.consumeToken();
        return this.functionDecl(labels);
      }

      case Token.DEFAULT: {
        this.consumeToken();
        this.reportError("msg.XML.not.available");
      }

      case Token.NAME: {
        var lineno = this.ts.getLineno();
        this.setCheckForLabel();
        try {
            statement = new ExpStatement(labels, this.expr(false), lineno, this.source);
        } catch ( e ) {
            if ( e instanceof LabelException ) {
                // Label found!
                if ( this.allLabelSet.contains(e.label) ) this.reportError("msg.dup.label");
                this.allLabelSet.add(e.label);
                labels.push(e.label);
                try {
                    statement = this.statementHelper(labels);
                } finally {
                    this.allLabelSet.remove(e.label);
                }
                return statement;
            } else {
                throw e;
            }
        }
        break;
      }

      default: {
        var lineno = this.ts.getLineno();
        statement = new ExpStatement(labels, this.expr(false), lineno, this.source);
        break;
      }
    }

    switch ( this.peekTokenOrEOL() ) {
      case Token.SEMI:
        // Consume ';' as a part of statement
        this.consumeToken();
        break;
      case Token.ERROR:
      case Token.EOF:
      case Token.EOL:
      case Token.RC:
        // Autoinsert ;
        break;
      default:
        // Report error if no EOL or autoinsert ; otherwise
        this.reportError("msg.no.semi.stmt");
    }

    return statement;
};

proto.condition = function ( )
{
    this.mustMatchToken(Token.LP, "msg.no.paren.cond");
    var exp = this.expr(false);
    this.mustMatchToken(Token.RP, "msg.no.paren.after.cond");
    if ( exp instanceof SimpleAssignExpression ) this.addWarning("msg.assign.cond");
    return exp;
};

// match a NAME; return null if no match.
proto.matchJumpLabelName = function ( token )
{
    if ( this.peekTokenOrEOL() !== Token.NAME ) return null;
    var label = new Identifier(this.ts.getString());
    this.consumeToken();
    switch ( token ) {
      case Token.CONTINUE:
        if ( !this.loopLabelSet.contains(label) ) {
            this.reportError("msg.undef.label");
        }
        break;
      case Token.BREAK:
        if ( !this.allLabelSet.contains(label) ) {
            this.reportError("msg.undef.label");
        }
        break;
      default:
        throw Kit.codeBug();
    }
    return label;
};

proto.statementsInSwitch = function ( )
{
    var head, cell;
    head = cell = cons(null, nil());
    clauseLoop: for (;;) {
        switch ( this.peekToken() ) {
          case Token.ERROR:
          case Token.EOF:
          case Token.RC:
          case Token.CASE:
            break clauseLoop;
          case Token.DEFAULT:
            this.consumeToken();
            var tt = this.peekToken();
            this.ungetToken(Token.DEFAULT);
            if ( tt === Token.COLON ) break clauseLoop;
            // fall thru
          default:
            cell = cell.cdr = cons(this.statement(), cell.cdr);
        }
    }
    return head.cdr;
};

proto.variables = function ( inForInit )
{
    var decls = [];
    for (;;) {
        this.mustMatchToken(Token.NAME, "msg.bad.var");
        var name = new Identifier(this.ts.getString());
        var init = this.matchToken(Token.ASSIGN)
                     ?  this.assignExpr(inForInit)
                     :  null;
        decls.push({id: name, exp: init});
        if ( !this.matchToken(Token.COMMA) ) break;
    }
    return decls;
};

proto.expr = function ( inForInit )
{
    var exp = this.assignExpr(inForInit);
    while ( this.matchToken(Token.COMMA) ) {
        exp = new CommaExpression(exp, this.assignExpr(inForInit));
    }
    return exp;
};

proto.assignExpr = function ( inForInit )
{
    var exp = this.condExpr(inForInit);
    var tt  = this.peekToken();
    if ( tt < Token.FIRST_ASSIGN || Token.LAST_ASSIGN < tt ) return exp;

    if ( !exp.hasLvalue() ) this.reportError("msg.bad.assign.left");

    switch ( this.nextToken() ) {
      case Token.ASSIGN:
        return new SimpleAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_BITOR:
        return new BitOrAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_BITXOR:
        return new BitXorAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_BITAND:
        return new BitAndAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_LSH:
        return new LShiftAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_RSH:
        return new RShiftAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_URSH:
        return new URShiftAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_ADD:
        return new AddAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_SUB:
        return new SubAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_MUL:
        return new MulAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_DIV:
        return new DivAssignExpression(exp, this.assignExpr(inForInit));
      case Token.ASSIGN_MOD:
        return new ModAssignExpression(exp, this.assignExpr(inForInit));
      default:
        throw Kit.codeBug();
    }
};

proto.condExpr = function ( inForInit )
{
    var exp = this.orExpr(inForInit);
    if ( !this.matchToken(Token.HOOK) ) return exp;
    var ifTrue = this.assignExpr(false);
    this.mustMatchToken(Token.COLON, "msg.no.colon.cond");
    var ifFalse = this.assignExpr(inForInit);
    return new ConditionalExpression(exp, ifTrue, ifFalse);
};

proto.orExpr = function ( inForInit )
{
    var exp = this.andExpr(inForInit);
    while ( this.matchToken(Token.OR) ) {
        exp = new OrExpression(exp, this.andExpr(inForInit));
    }
    return exp;
};

proto.andExpr = function ( inForInit )
{
    var exp = this.bitOrExpr(inForInit);
    while ( this.matchToken(Token.AND) ) {
        exp = new AndExpression(exp, this.bitOrExpr(inForInit));
    }
    return exp;
};

proto.bitOrExpr = function ( inForInit )
{
    var exp = this.bitXorExpr(inForInit);
    while ( this.matchToken(Token.BITOR) ) {
        exp = new BitOrExpression(exp, this.bitXorExpr(inForInit));
    }
    return exp;
};

proto.bitXorExpr = function ( inForInit )
{
    var exp = this.bitAndExpr(inForInit);
    while ( this.matchToken(Token.BITXOR) ) {
        exp = new BitXorExpression(exp, this.bitAndExpr(inForInit));
    }
    return exp;
};

proto.bitAndExpr = function ( inForInit )
{
    var exp = this.eqExpr(inForInit);
    while ( this.matchToken(Token.BITAND) ) {
        exp = new BitAndExpression(exp, this.eqExpr(inForInit));
    }
    return exp;
};

proto.eqExpr = function ( inForInit )
{
    var exp = this.relExpr(inForInit);
    for (;;) {
        var constructor;
        switch ( this.peekToken() ) {
          case Token.EQ:
            constructor = EqualExpression;
            break;
          case Token.NE:
             constructor = NotEqualExpression;
            break;
          case Token.SHEQ:
            constructor = StrictEqualExpression;
            break;
          case Token.SHNE:
            constructor = StrictNotEqualExpression;
            break;
          default:
            return exp;
        }
        this.consumeToken();
        exp = new constructor(exp, this.relExpr(inForInit));
    }
};

proto.relExpr = function ( inForInit )
{
    var exp = this.shiftExpr();
    for (;;) {
        var constructor;
        switch ( this.peekToken() ) {
          case Token.IN:
            if ( inForInit ) return exp;
            constructor = InExpression;
            break;
          case Token.INSTANCEOF:
            constructor = InstanceofExpression;
            break;
          case Token.LE:
            constructor = LessEqualExpression;
            break;
          case Token.LT:
            constructor = LessThanExpression;
            break;
          case Token.GE:
            constructor = GreaterEqualExpression;
            break;
          case Token.GT:
            constructor = GreaterThanExpression;
            break;
          default:
            return exp;
        }
        this.consumeToken();
        exp = new constructor(exp, this.shiftExpr());
    }
};

proto.shiftExpr = function ( )
{
    var exp = this.addExpr();
    for (;;) {
        var constructor;
        switch ( this.peekToken() ) {
          case Token.LSH:
            constructor = LShiftExpression;
            break;
          case Token.RSH:
            constructor = RShiftExpression;
            break;
          case Token.URSH:
            constructor = URShiftExpression;
            break;
          default:
            return exp;
        }
        this.consumeToken();
        exp = new constructor(exp, this.addExpr());
    }
};

proto.addExpr = function ( )
{
    var exp = this.mulExpr();
    for (;;) {
        var constructor;
        switch ( this.peekToken() ) {
          case Token.ADD:
            constructor = AddExpression;
            break;
          case Token.SUB:
            constructor = SubExpression;
            break;
          default:
            return exp;
        }
        this.consumeToken();
        exp = new constructor(exp, this.mulExpr());
    }
};

proto.mulExpr = function ( )
{
    var exp = this.unaryExpr();
    for (;;) {
        var constructor;
        switch ( this.peekToken() ) {
          case Token.MUL:
            constructor = MulExpression;
            break;
          case Token.DIV:
            constructor = DivExpression;
            break;
          case Token.MOD:
            constructor = ModExpression;
            break;
          default:
            return exp;
        }
        this.consumeToken();
        exp = new constructor(exp, this.unaryExpr());
    }
};

proto.unaryExpr = function ( )
{
    var constructor;
    var needLvalue = null;
    switch( this.peekToken() ) {
      case Token.VOID:
        constructor = VoidExpression;
        break;
      case Token.NOT:
        constructor = NotExpression;
        break;
      case Token.BITNOT:
        constructor = BitNotExpression;
        break;
      case Token.TYPEOF:
        constructor = TypeofExpression;
        break;
      case Token.ADD:
        constructor = PosExpression;
        break;
      case Token.SUB:
        constructor = NegExpression;
        break;
      case Token.INC:
        constructor = PreIncExpression;
        needLvalue = "msg.bad.incr";
        break;
    case Token.DEC:
        constructor = PreDecExpression;
        needLvalue = "msg.bad.decr";
        break;
    case Token.DELPROP:
        constructor = DeleteExpression;
        break;
    default:
        var exp = this.memberExpr(true);
        // Don't look across a newline boundary for a postfix incop.
        switch ( this.peekTokenOrEOL() ) {
          case Token.INC:
            if ( !exp.hasLvalue() ) this.reportError("msg.bad.incr");
            this.consumeToken();
            return new PostIncExpression(exp);
          case Token.DEC:
            if ( !exp.hasLvalue() ) this.reportError("msg.bad.decr");
            this.consumeToken();
            return new PostDecExpression(exp);
          default:
            return exp;
        }
    }
    this.consumeToken();
    var exp = this.unaryExpr();
    if ( needLvalue  &&  !exp.hasLvalue() ) this.reportError(needLvalue);
    return new constructor(exp);
};

proto.argumentList = function ( )
{
    if ( this.matchToken(Token.RP) ) return [];
    var args = [];
    do {
        args.push( this.assignExpr(false) );
    } while ( this.matchToken(Token.COMMA) );
    this.mustMatchToken(Token.RP, "msg.no.paren.arg");
    return args;
};

proto.memberExpr = function ( allowCallSyntax )
{
    var base;
    if ( this.matchToken(Token.NEW) ) {
        var func = this.memberExpr(false);
        var args = this.matchToken(Token.LP)
                     ?  this.argumentList()
                     :  [];
        base = new NewExpression(func, args);
    } else {
        base = this.primaryExpr();
    }
    return this.memberExprTail(allowCallSyntax, base);
}

proto.memberExprTail = function ( allowCallSyntax, base )
{
    tailLoop: for (;;) {
        switch ( this.peekToken() ) {
          case Token.DOTDOT:
            this.reportError("msg.XML.not.available");

          case Token.DOT: {
            this.consumeToken();
            switch ( this.nextToken() ) {
              case Token.NAME:
                base = new DotAccessor(base, new Identifier(this.ts.getString()));
                break;
              case Token.MUL:
                this.reportError("msg.XML.not.available");
              case Token.XMLATTR:
                this.reportError("msg.XML.not.available");
              default:
                this.reportError("msg.no.name.after.dot");
            }
          }
          break;

          case Token.DOTQUERY:
            this.reportError("msg.XML.not.available");

          case Token.LB:
            this.consumeToken();
            base = new BracketAccessor(base, this.expr(false));
            this.mustMatchToken(Token.RB, "msg.no.bracket.index");
            break;

          case Token.LP:
            if ( !allowCallSyntax ) break tailLoop;
            this.consumeToken();
            base = new CallExpression(base, this.argumentList());
            break;

          default:
            break tailLoop;
        }
    }
    return base;
};

proto.primaryExpr = function ( )
{
    var exp;
    var ttFlagged = this.nextFlaggedToken();
    var tt = ttFlagged & CLEAR_TI_MASK;
    switch ( tt ) {

      case Token.FUNCTION:
        return this.functionExpr();

      case Token.LB: {
        var elems = [];
        elemLoop: for (;;) {
            switch ( this.peekToken() ) {
              case Token.RB:
                this.consumeToken();
                break elemLoop;
              case Token.COMMA:
                while ( this.matchToken(Token.COMMA) ) {
                    elems.push(new Elision());
                }
                break;
              default:
                elems.push(this.assignExpr(false));
                if ( this.matchToken(Token.COMMA) ) {
                    continue elemLoop;
                } else if ( this.matchToken(Token.RB) ) {
                    break elemLoop;
                } else {
                    this.reportError("msg.no.bracket.arg");
                }
            }
        }
        return new ArrayInitializer(elems);
      }

      case Token.LC: {
        var pairs = [];
        commaloop: do {
            var prop;
            switch ( this.peekToken() ) {
              case Token.NAME:
                this.consumeToken();
                prop = new Identifier(this.ts.getString());
                break;
              case Token.STRING:
                this.consumeToken();
                prop = new StringLiteral(this.ts.getString());
                break;
              case Token.NUMBER:
                this.consumeToken();
                prop = new NumberLiteral(this.ts.getString());
                break;
              case Token.RC:
                // trailing comma is OK.
                break commaloop;
            default:
                this.reportError("msg.bad.prop");
                break commaloop;
            }
            this.mustMatchToken(Token.COLON, "msg.no.colon.prop");
            pairs.push({prop:prop, exp:this.assignExpr(false)});
        } while ( this.matchToken(Token.COMMA) );
        this.mustMatchToken(Token.RC, "msg.no.brace.prop");
        return new ObjectInitializer(pairs);
      }

      case Token.LP:
        var exp = this.expr(false);
        this.mustMatchToken(Token.RP, "msg.no.paren");
        return exp;

      case Token.XMLATTR:
        this.reportError("msg.XML.not.available");

      case Token.NAME:
        var name = new Identifier(this.ts.getString());
        if ( ttFlagged & TI_CHECK_LABEL ) {
            if ( this.matchToken(Token.COLON) ) throw new LabelException(name);
        }
        return name;

      case Token.NUMBER:
        return new NumberLiteral(this.ts.getString());

      case Token.STRING:
        return new StringLiteral(this.ts.getString());

      case Token.DIV:
      case Token.ASSIGN_DIV:
        // Got / or /= which should be treated as regexp in fact
        this.ts.readRegExp(tt);
        return new RegExpLiteral(this.ts.getString());

      case Token.NULL:
        return new NullLiteral();

      case Token.THIS:
        return new ThisExpression();

      case Token.TRUE:
        return new TrueLiteral();

      case Token.FALSE:
        return new FalseLiteral();

      case Token.RESERVED:
        this.reportError("msg.reserved.id");
        break;

      case Token.ERROR:
        /* the scanner or one of its subroutines reported the error. */
        break;

      case Token.EOF:
        this.reportError("msg.unexpected.eof");
        break;

      default:
        this.reportError("msg.syntax");
        break;
    }
    return null;    // should never reach here
}

            return {
                Parser: Parser
            };
        }();
    }
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.Parser = Parser;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( this.Concurrent.Thread.Compiler.CfConvert === undefined ) this.Concurrent.Thread.Compiler.CfConvert = undefined;
    if ( this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError === undefined ) this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Data.Error ) {
with ( Concurrent.Thread ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var IL = Concurrent.Thread.Compiler.IntermediateLanguage;

var Cf = "$Concurrent_Thread_Compiler_Cf";

function CfConvert ( func ) {
    var cache = new IdentifierMap();
    var start = CfTarget(func.start, cache);
    var cache2 = new IdentifierMap();
    cache.values().forEach(function( it ){
        cache2.put(new Identifier(it.id), it);
    });
    var body  = cons(null, nil());
    append = adder(body);
    cacheToList(cache2).forEach(function( it ){
        return append(cache2.get(it));
    });
    return new IL.Function(func.name, func.params, func.vars, body.cdr, start);
}

function cacheToList ( cache ) {
    // Resolves exception-dependency and sort blocks in valid order.
    var blocks = [];
    var depends = new IdentifierMap();
    cache.values().forEach(function( it ){
        blocks.push(it);
        depends.put(
            new Identifier(it.id),
            it.exception instanceof IL.Block ? new Identifier(it.exception.id) : undefined
        );
    });
    return check_cyclic(depends);
}

var CyclicExceptionHandlerError = Error.extend(
    function ( $super, message ) { $super(message); },
    {name: NAMESPACE + ".CyclicExceptionHandlerError"}
);

function check_cyclic ( depends ) {
    var ok = {};
    function traverse ( id, path ) {
        if ( ok[id] ) return "OK";
        var next = depends.get(id);
        if ( !next ) {
            ok[id] = true;
            path.push(id);
            return "OK";
        }
        path.forEach(function( it ){
            if ( it.valueOf() == id.valueOf() ) {
                throw new CyclicExceptionHandlerError("cyclic exception handler: " + path.concat([id]).join(" -> "));
            }
        });
        path.push(id);
        traverse(next, path);
        ok[id] = true;
        return "OK";
    }
    var result = [];
    depends.keys().forEach(function( it ){
        var path = [];
        traverse(it, path);
        result = path.concat(result);
    });
    return result.reverse();
}

function CfTarget ( b, cache ) {
    if ( b === "return" || b === "throw" ) return b;
    if ( cache.get(new Identifier(b.id)) ) return cache.get(new Identifier(b.id));
    return b[Cf](cache);
}

IL.GotoBlock.prototype[Cf] = function ( cache ) {
    var block = new IL.GotoBlock();
    cache.put(new Identifier(this.id), block);
    block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
    block.body      = this.body.map(function( it ){ return it[Cf](cache); });
    block.arg       = this.arg[Cf](cache);
    block.target    = CfTarget(this.target, cache);
    block.exception = CfTarget(this.exception, cache);
    return block;
};

IL.CallBlock.prototype[Cf] = function ( cache ) {
    var block = new IL.CallBlock();
    cache.put(new Identifier(this.id), block);
    block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
    block.body      = this.body.map(function( it ){ return it[Cf](cache); });
    block.this_val  = this.this_val[Cf](cache);
    block.func      = this.func[Cf](cache);
    block.args      = this.args.map(function( it ){ return it[Cf](cache); });
    block.target    = CfTarget(this.target, cache);
    block.exception = CfTarget(this.exception, cache);
    return block;
};

IL.NewBlock.prototype[Cf] = function ( cache ) {
    var block = new IL.NewBlock();
    cache.put(new Identifier(this.id), block);
    block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
    block.body      = this.body.map(function( it ){ return it[Cf](cache); });
    block.func      = this.func[Cf](cache);
    block.args      = this.args.map(function( it ){ return it[Cf](cache); });
    block.target    = CfTarget(this.target, cache);
    block.exception = CfTarget(this.exception, cache);
    return block;
};

IL.ExpStatement.prototype[Cf] = function ( cache ) {
    return new IL.ExpStatement(
        this.exp[Cf](cache)
    );
};

IL.CondStatement.prototype[Cf] = function ( cache ) {
    return new IL.CondStatement(
        this.cond[Cf](cache),
        CfTarget(this.target, cache)
    );
};

IL.RecvStatement.prototype[Cf] = function ( cache ) {
    return new IL.RecvStatement(
        this.assignee[Cf](cache)
    );
};

IL.EnumStatement.prototype[Cf] = function ( cache ) {
    return new IL.EnumStatement(
        this.exp[Cf](cache),
        this.assignee[Cf](cache)
    );
};

Expression.prototype[Cf] = function ( cache ) {
    return this;
};

UnaryExpression.prototype[Cf] = function ( cache ) {
    return new this.constructor(this.exp[Cf](cache));
};

BinaryExpression.prototype[Cf] = function ( cache ) {
    return new this.constructor(this.left[Cf](cache), this.right[Cf](cache));
};

ArrayInitializer.prototype[Cf] = function ( cache ) {
    return new ArrayInitializer(this.elems.map(function( it ){
        return it[Cf](cache);
    }));
};

FunctionExpression.prototype[Cf] = function ( cache ) {
    return prepareTree(this);
};

ObjectInitializer.prototype[Cf] = function ( cache ) {
    return new ObjectInitializer(this.pairs.map(function( it ){
        return { prop: it.prop,  exp: it.exp[Cf](cache) };
    }));
};

DotAccessor.prototype[Cf] = function ( cache ) {
    return new DotAccessor(this.base[Cf](cache), this.prop);
};

ConditionalExpression.prototype[Cf] = function ( cache ) {
    return new ConditionalExpression(
        this.cond[Cf](cache),
        this.texp[Cf](cache),
        this.fexp[Cf](cache)
    );
};

            return {
                CfConvert: CfConvert, CyclicExceptionHandlerError: CyclicExceptionHandlerError
            };
        }();
    }
}
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CfConvert = CfConvert;
    this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError = CyclicExceptionHandlerError;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.CsConvert === undefined ) this.Concurrent.Thread.Compiler.CsConvert = undefined;
with ( function(){
with ( Data.Functional ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var IL = Concurrent.Thread.Compiler.IntermediateLanguage;

var Cs = "Concurrent.Thread.Compiler.CsConvert";
var STACK_VAR = "$Concurrent_Thread_stack";

var undefinedExp = new VoidExpression(new NumberLiteral(0));
var emptyLabel   = new Identifier("");

function isStackVar ( v ) {
    return v instanceof Identifier
        && v.valueOf().match(/^$Concurrent_Thread_stack/);
}

function Context ( ) {
    this.stackVars = [];
    this.contBreak    = new IdentifierMap();
    this.contContinue = new IdentifierMap();
    this.contReturn   = "return";
    this.contThrow    = "throw";
    this.scopes       = [];
}

var proto = Context.prototype;

proto.getStackVar = function ( n ) {
    n = Math.floor(n);
    if ( isNaN(n) || n < 0 ) Kit.codeBug("must be integer greater than zero");
    for ( var i=this.stackVars.length;  i <= n;  i++ ) {
        this.stackVars[i] = new Identifier(STACK_VAR + i);
    }
    return this.stackVars[n];
};

proto.putBreakLabels = function ( labels, target ) {
    if ( !labels.length ) return this.contBreak;
    var restore = this.contBreak;
    this.contBreak = this.contBreak.clone();
    for ( var i=0;  i < labels.length;  i++ ) {
        this.contBreak.put(labels[i], target);
    }
    return restore;
};

proto.putBreakAndContinueLabels = function ( labels, breakTarget, continueTarget ) {
    if ( !labels.length ) {
        return {
            contBreak   : this.contBreak,
            contContinue: this.contContinue
        };
    }
    var restore = {
        contBreak   : this.contBreak,
        contContinue: this.contContinue
    };
    this.contBreak    = this.contBreak.clone();
    this.contContinue = this.contContinue.clone();
    for ( var i=0;  i < labels.length;  i++ ) {
        this.contBreak.put(labels[i], breakTarget);
        this.contContinue.put(labels[i], continueTarget);
    }
    return restore;
};

proto.getScopes = function ( ) {
    return this.scopes.slice(0, this.scopes.length);
};

proto.pushScope = function ( /* variable args */ ) {
    return this.scopes.push.apply(this.scopes, arguments);
};

proto.popScope = function ( ) {
    return this.scopes.pop();
};

proto.makeGotoBlock = function ( arg, target ) {
    return new IL.GotoBlock(this.getScopes(), nil(), arg, target, this.contThrow);
};

function CsConvert ( func ) {
    var context = new Context();
    var last_block = new IL.GotoBlock([], nil(), undefinedExp, "return", "throw");
    func.body  = CsStatements(func.body, list(last_block), context, 0);
    func.start = func.body.car;
    func.vars  = func.vars.concat(context.stackVars);
    return func;
}

function CsStatements ( stmts, follows, ctxt, sttop ) {
    if ( stmts.isNil() ) return follows;
    follows = CsStatements(stmts.cdr, follows, ctxt, sttop);
    return stmts.car[Cs](follows, ctxt, sttop);
}

function CsReference ( exp, ctxt, sttop, rest ) {  // Expression -> Context -> Int -> (Expression -> <Block>) -> <Block>
    if ( exp instanceof DotAccessor ) {
        var e = new DotAccessor(ctxt.getStackVar(sttop), exp.prop);
        var follows = rest(e, sttop+1);
        return exp.base[Cs](follows, ctxt, sttop);
    } else if ( exp instanceof BracketAccessor ) {
        var e = new BracketAccessor(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1));
        var follows = rest(e, sttop+2);
        follows = exp.right[Cs](follows, ctxt, sttop+1);
        return exp.left[Cs](follows, ctxt, sttop);
    } else if ( exp instanceof Identifier ) {
        return rest(exp, sttop);
    } else {
        var follows = rest(ctxt.getStackVar(sttop), sttop+1);
        return exp[Cs](follows, ctxt, sttop);
    }
}

EmptyStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    return follows;
};

Block.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var restore = ctxt.putBreakLabels(this.labels, follows.car);
    follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows);
    try {
        return CsStatements(this.body, follows, ctxt, sttop);
    } finally {
        ctxt.contBreak = restore;
    }
};

ExpStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    return this.exp[Cs](follows, ctxt, sttop);
};

IfStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
    var restore = ctxt.putBreakLabels(this.labels, next_block);
    try {
        follows = this.body[Cs](follows, ctxt, sttop);
        follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
        return this.cond[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak = restore;
    }
};

IfElseStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
    var restore = ctxt.putBreakLabels(this.labels, next_block);
    try {
        follows = this.tbody[Cs](follows, ctxt, sttop);
        var true_block = follows.car;
        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
        follows = this.fbody[Cs](follows, ctxt, sttop);
        follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), true_block) );
        return this.cond[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak = restore;
    }
};

DoWhileStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block  = follows.car;
    var first_block = ctxt.makeGotoBlock(undefinedExp, null);
    follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
    if ( this.cond.containsFunctionCall() ) {
        follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), first_block) );
        follows = this.cond[Cs](follows, ctxt, sttop);
    } else {
        follows.car.prependStatement( new IL.CondStatement(this.cond, first_block) );
    }
    var continue_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
    var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, continue_block);
    try {
        follows = this.body[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak    = restore.contBreak;
        ctxt.contContinue = restore.contContinue;
    }
    first_block.target = follows.car;
    return cons( ctxt.makeGotoBlock(undefinedExp, first_block),
                 cons(first_block, follows) );
};

WhileStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block  = follows.car;
    var first_block = ctxt.makeGotoBlock(undefinedExp, null);
    follows = cons( ctxt.makeGotoBlock(undefinedExp, first_block), follows );
    var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, first_block);
    try {
        follows = this.body[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak    = restore.contBreak;
        ctxt.contContinue = restore.contContinue;
    }
    if ( this.cond.containsFunctionCall() ) {
        follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
        follows = this.cond[Cs](follows, ctxt, sttop);
    } else {
        follows.car.prependStatement( new IL.CondStatement(new NotExpression(this.cond), next_block) );
    }
    first_block.target = follows.car;
    return cons( ctxt.makeGotoBlock(undefinedExp, first_block),
                 cons(first_block, follows) );
};

ForStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    var last_block = ctxt.makeGotoBlock(undefinedExp, null);
    follows = cons(last_block, follows);
    if ( this.incr ) follows = this.incr[Cs](follows, ctxt, sttop);
    var incr_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
    var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, incr_block);
    try {
        follows = this.body[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak    = restore.contBreak;
        ctxt.contContinue = restore.contContinue;
    }
    if ( this.cond ) {
        if ( this.cond.containsFunctionCall() ) {
            follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
            follows = this.cond[Cs](follows, ctxt, sttop);
        } else {
            follows.car.prependStatement( new IL.CondStatement(new NotExpression(this.cond), next_block) );
        }
    }
    last_block.target = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
    if ( this.init ) {
        follows = this.init[Cs](follows, ctxt, sttop);
    }
    return follows;
};

ForInStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( !this.lhs.hasLvalue() ) Kit.codeBug('for-in requires lvalue on the left hand side of "in": ' + this);
    var next_block = follows.car;
    var loop_block = ctxt.makeGotoBlock(undefinedExp, null);
    follows = cons( ctxt.makeGotoBlock(undefinedExp, loop_block), follows );
    var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, loop_block);
    try {
        follows = this.body[Cs](follows, ctxt, sttop+2);
    } finally {
        ctxt.contBreak    = restore.contBreak;
        ctxt.contContinue = restore.contContinue;
    }
    if ( this.lhs.containsFunctionCall() ) {
        follows = CsReference(this.lhs, ctxt, sttop+2, function( exp ){
            follows.car.prependStatement( make_assign(
                exp,
                new BracketAccessor(
                    ctxt.getStackVar(sttop),
                    new PostIncExpression(ctxt.getStackVar(sttop+1))
                )
            ) );
            return follows;
        });
    } else {
        follows.car.prependStatement( make_assign(
            this.lhs,
            new BracketAccessor(
                ctxt.getStackVar(sttop),
                new PostIncExpression(ctxt.getStackVar(sttop+1))
            )
        ) );
    }
    follows.car.prependStatement( new IL.CondStatement(
        new GreaterEqualExpression(
            ctxt.getStackVar(sttop+1),
            new DotAccessor(ctxt.getStackVar(sttop), new Identifier("length"))
        ),
        next_block
    ) );
    loop_block.target = follows.car;
    follows = cons( loop_block, follows );
    follows = cons( ctxt.makeGotoBlock(undefinedExp, loop_block), follows );
    follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop+1), new NumberLiteral(0)) );
    if ( this.exp.containsFunctionCall() ) {
        follows.car.prependStatement( new IL.EnumStatement(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop)) );
        follows = this.exp[Cs](follows, ctxt, sttop);
    } else {
        follows.car.prependStatement( new IL.EnumStatement(this.exp, ctxt.getStackVar(sttop)) );
    }
    return follows;
};

ContinueStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    return cons(
        ctxt.makeGotoBlock(
            undefinedExp,
            ctxt.contContinue.get( this.target ? this.target : emptyLabel )
        ),
        follows
    );
};

BreakStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var restore = ctxt.putBreakLabels(this.labels, follows.car);
    try {
        return cons(
            ctxt.makeGotoBlock(
                undefinedExp,
                ctxt.contBreak.get( this.target ? this.target : emptyLabel )
            ),
            follows
        );
    } finally {
        ctxt.contBreak = restore;
    }
};

ReturnStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.exp ) {
        if ( this.exp.containsFunctionCall() ) {
            follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contReturn), follows );
            return this.exp[Cs](follows, ctxt, sttop);
        } else {
            return cons( ctxt.makeGotoBlock(this.exp, ctxt.contReturn), follows );
        }
    } else {
        return cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contReturn), follows );
    }
};

WithStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    var restore = ctxt.putBreakLabels(this.labels, next_block);
    try {
        ctxt.pushScope(ctxt.getStackVar(sttop));
        try {
            follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
            follows = this.body[Cs](follows, ctxt, sttop+1);
        } finally {
            ctxt.popScope();
        }
        follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
        return this.exp[Cs](follows, ctxt, sttop);
    } finally {
        ctxt.contBreak = restore;
    }
};

SwitchStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    var restore = ctxt.putBreakLabels(this.labels.concat(emptyLabel) , next_block);
    try {
        var default_target  = next_block;
        var cond_and_target = this.clauses.reverse().map(function( clause ){
            follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
            follows = CsStatements(clause.body, follows, ctxt, sttop);
            var clause_block = follows.car;
            if ( clause instanceof DefaultClause ) {
                default_target = clause_block;
                ignore();
            } else {
                return {cond:clause.exp, target:clause_block};
            }
        });
        follows = cons( ctxt.makeGotoBlock(undefinedExp, default_target), follows );
        cond_and_target.forEach(function( it ){
            if ( it.cond.containsFunctionCall() ) {
                follows.car.prependStatement(
                    new IL.CondStatement(
                        new StrictEqualExpression(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1)),
                        it.target
                    )
                );
                follows = it.cond[Cs](follows, ctxt, sttop+1);
            } else {
                follows.car.prependStatement(
                    new IL.CondStatement(
                        new StrictEqualExpression(ctxt.getStackVar(sttop), it.cond),
                        it.target
                    )
                );
            }
        });
        return this.exp[Cs](follows, ctxt,sttop);
    } finally {
        ctxt.contBreak = restore;
    }
};

ThrowStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.exp.containsFunctionCall() ) {
        follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contThrow), follows );
        return this.exp[Cs](follows, ctxt, sttop);
    } else {
        return cons( ctxt.makeGotoBlock(this.exp, ctxt.contThrow), follows );
    }
};

TryCatchStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
    var restore = ctxt.putBreakLabels(this.labels, next_block);
    try {
        follows = this.catchBlock[Cs](follows, ctxt, sttop);
        follows.car.prependStatement( new IL.RecvStatement(this.variable) );
        var storeContThrow = ctxt.contThrow;
        ctxt.contThrow = follows.car;
        try {
            follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
            return this.tryBlock[Cs](follows, ctxt, sttop);
        } finally {
            ctxt.contThrow = storeContThrow;
        }
    } finally {
        ctxt.contBreak = restore;
    }
};

TryFinallyStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var next_block = follows.car;
    follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
    var restoreBreak = ctxt.putBreakLabels(this.labels, next_block);
    try {
        var self = this;

        var contBreak = new IdentifierMap();
        ctxt.contBreak.keys().forEach(function( label ){
            follows = cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contBreak.get(label)), follows );
            follows = self.finallyBlock[Cs](follows, ctxt, sttop);
            contBreak.put(label, follows.car);
        });

        var contContinue = new IdentifierMap();
        ctxt.contContinue.keys().forEach(function( label ){
            follows = cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contContinue.get(label)), follows );
            follows = self.finallyBlock[Cs](follows, ctxt, sttop);
            contContinue.put(label, follows.car);
        });

        follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contReturn), follows );
        follows = this.finallyBlock[Cs](follows, ctxt, sttop+1);
        follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
        var contReturn = follows.car;

        follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contThrow), follows );
        follows = this.finallyBlock[Cs](follows, ctxt, sttop+1);
        follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
        var contThrow = follows.car;

        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
        follows = this.finallyBlock[Cs](follows, ctxt, sttop);

        var restoreContinue = ctxt.contContinue;
        var restoreReturn   = ctxt.contReturn;
        var restoreThrow    = ctxt.contThrow;
        ctxt.contBreak    = contBreak;
        ctxt.contContinue = contContinue;
        ctxt.contReturn   = contReturn;
        ctxt.contThrow    = contThrow;
        try {
            return this.tryBlock[Cs](follows, ctxt, sttop);
        } finally {
            ctxt.contContinue = restoreContinue;
            ctxt.contReturn   = restoreReturn;
            ctxt.contThrow    = restoreThrow;
        }
    } finally {
        ctxt.contBreak = restoreBreak;
    }
};

function make_assign ( left, right ) {
    return new IL.ExpStatement( new SimpleAssignExpression(left, right) );
}

Expression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), this) );
    return follows;
};

ArrayInitializer.prototype[Cs] = function ( follows, ctxt, sttop ) {
    for ( var asis_from=this.elems.length-1;  asis_from >= 0;  asis_from-- ) {
        if ( this.elems[asis_from].containsFunctionCall() ) break;
    }
    asis_from++;
    var elems = [];
    for ( var i=0;  i < asis_from;  i++ ) {
        elems[i] = ctxt.getStackVar(sttop+i);
    }
    for ( ;  i < this.elems.length;  i++ ) {
        elems[i] = this.elems[i];
    }
    follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ArrayInitializer(elems)) );
    for ( var i=asis_from-1;  i >= 0;  i-- ) {
        follows = this.elems[i][Cs](follows, ctxt, sttop+i);
    }
    return follows;
};

ObjectInitializer.prototype[Cs] = function ( follows, ctxt, sttop ) {
    for ( var asis_from=this.pairs.length-1;  asis_from >= 0;  asis_from-- ) {
        if ( this.pairs[asis_from].exp.containsFunctionCall() ) break;
    }
    asis_from++;
    var pairs = [];
    for ( var i=0;  i < asis_from;  i++ ) {
        pairs[i] = {prop:this.pairs[i].prop, exp:ctxt.getStackVar(sttop+i)};
    }
    for ( ;  i < this.pairs.length;  i++ ) {
        pairs[i] = this.pairs[i];
    }
    follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ObjectInitializer(pairs)) );
    for ( var i=asis_from-1;  i >= 0;  i-- ) {
        follows = this.pairs[i].exp[Cs](follows, ctxt, sttop+i);
    }
    return follows;
};

UnaryExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.exp.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new this.constructor(ctxt.getStackVar(sttop))) );
        return this.exp[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

BinaryExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.right.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(
            ctxt.getStackVar(sttop),
            new this.constructor(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1))
        ) );
        follows = this.right[Cs](follows, ctxt, sttop+1);
        return this.left[Cs](follows, ctxt, sttop);
    } else if ( this.left.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(
            ctxt.getStackVar(sttop),
            new this.constructor(ctxt.getStackVar(sttop), this.right)
        ) );
        return this.left[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

DotAccessor.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.base.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(
            ctxt.getStackVar(sttop),
            new DotAccessor(ctxt.getStackVar(sttop), this.prop)
        ) );
        return this.base[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

CallExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var self = this;
    return CsReference(this.func, ctxt, sttop, function ( func, sttop2 ) {
        for ( var asis_from=self.args.length-1;  asis_from >= 0;  asis_from-- ) {
            if ( self.args[asis_from].containsFunctionCall() ) break;
        }
        asis_from++;
        var args = [];
        for ( var i=0;  i < asis_from;  i++ ) {
            args[i] = ctxt.getStackVar(sttop2+i);
        }
        for ( ;  i < self.args.length;  i++ ) {
            args[i] = self.args[i];
        }
        follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
        follows = cons( new IL.CallBlock(
                            ctxt.getScopes(),
                            nil(),
                            func instanceof DotAccessor     ? func.base :
                            func instanceof BracketAccessor ? func.left : new NullLiteral(),
                            func,
                            args,
                            follows.car,
                            ctxt.contThrow
                        ), follows );
        for ( var i=asis_from-1;  i >= 0;  i-- ) {
            follows = self.args[i][Cs](follows, ctxt, sttop2+i);
        }
        return follows;
    });
};

NewExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    for ( var asis_from=this.args.length-1;  asis_from >= 0;  asis_from-- ) {
        if ( this.args[asis_from].containsFunctionCall() ) break;
    }
    asis_from++;
    var args = [];
    for ( var i=0;  i < asis_from;  i++ ) {
        args[i] = ctxt.getStackVar(sttop+1+i);
    }
    for ( ;  i < this.args.length;  i++ ) {
        args[i] = this.args[i];
    }
    follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
    follows = cons( new IL.NewBlock(
                        ctxt.getScopes(),
                        nil(),
                        ctxt.getStackVar(sttop),
                        args,
                        follows.car,
                        ctxt.contThrow
                    ), follows );
    for ( var i=asis_from-1;  i >= 0;  i-- ) {
        follows = this.args[i][Cs](follows, ctxt, sttop+1+i);
    }
    this.func[Cs](follows, ctxt, sttop);
    return follows;
};

AssignExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    var self = this;
    if ( this.right.containsFunctionCall() ) {
        return CsReference(this.left, ctxt, sttop, function ( left, sttop2 ) {
            follows.car.prependStatement( make_assign(
                ctxt.getStackVar(sttop),
                new self.constructor(left, ctxt.getStackVar(sttop2))
            ) );
            return self.right[Cs](follows, ctxt, sttop2);
        });
    } else if ( this.left.containsFunctionCall() ) {
        return CsReference(this.left, ctxt, sttop, function ( left, sttop2 ) {
            follows.car.prependStatement( make_assign(
                ctxt.getStackVar(sttop),
                new self.constructor(left, self.right)
            ) );
            return follows;
        });
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

AndExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.right.containsFunctionCall() ) {
        var next_block = follows.car;
        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
        follows = this.right[Cs](follows, ctxt, sttop);
        follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
        return this.left[Cs](follows, ctxt, sttop);
    } else if ( this.left.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new AndExpression(ctxt.getStackVar(sttop), this.right)) );
        return this.left[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

OrExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.right.containsFunctionCall() ) {
        var next_block = follows.car;
        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
        follows = this.right[Cs](follows, ctxt, sttop);
        follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), next_block) );
        return this.left[Cs](follows, ctxt, sttop);
    } else if ( this.left.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new OrExpression(ctxt.getStackVar(sttop), this.right)) );
        return this.left[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

ConditionalExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
    if ( this.texp.containsFunctionCall() || this.fexp.containsFunctionCall() ) {
        var next_block = follows.car;
        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
        follows = this.texp[Cs](follows, ctxt, sttop);
        var true_block = follows.car;
        follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
        follows = this.fexp[Cs](follows, ctxt, sttop);
        follows.car.prependStatement(new IL.CondStatement(ctxt.getStackVar(sttop), true_block));
        return this.cond[Cs](follows, ctxt, sttop);
    } else if ( this.cond.containsFunctionCall() ) {
        follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ConditionalExpression(ctxt.getStackVar(sttop), this.texp, this.fexp)) );
        return this.cond[Cs](follows, ctxt, sttop);
    } else {
        return Expression.prototype[Cs].apply(this, arguments);
    }
};

            return {
                CsConvert: CsConvert
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CsConvert = CsConvert;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.CvConvert === undefined ) this.Concurrent.Thread.Compiler.CvConvert = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var IL = IntermediateLanguage;

var Cv = "$Concurrent_Thread_Compiler_CvConvert";

function CvConvert ( func ) {
    var vars  = new IdentifierSet()
    function add_vars ( /* variable arguments */ ) {
        return vars.add.apply(vars, arguments);
    }
    var decls     = cons(null, nil());
    var add_decls = adder(decls);
    for ( var c=func.body;  !c.isNil();  c=c.cdr ) {
        c.car = c.car[Cv](add_vars, add_decls);
    }
    return new IL.Function(func.name, func.params, vars.toArray(), concat(decls, func.body).cdr);
}

Statement.prototype[Cv] = function ( add_vars, add_decls ) {
    return this;
};

Block.prototype[Cv] = function ( add_vars, add_decls ) {
    for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
        c.car = c.car[Cv](add_vars, add_decls);
    }
    return this;
};

VarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    var assigns = [];
    for ( var i=0;  i < this.decls.length;  i++ ) {
        add_vars(this.decls[i].id);
        if ( this.decls[i].exp ) {
            assigns.push( new SimpleAssignExpression(this.decls[i].id, this.decls[i].exp) );
        }
    }
    if ( !assigns.length ) {
        return new EmptyStatement([], this.lineno, this.source);
    } else {
        var exp = assigns[0];
        for ( var i=1;  i < assigns.length;  i++ ) {
            exp = new CommaExpression(exp, assigns[i]);
        }
        return new ExpStatement([], exp, this.lineno, this.source);
    }
};

IfStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    this.body = this.body[Cv](add_vars, add_decls);
    return this;
};

IfElseStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    this.tbody = this.tbody[Cv](add_vars, add_decls);
    this.fbody = this.fbody[Cv](add_vars, add_decls);
    return this;
};

DoWhileStatement.prototype[Cv] = IfStatement.prototype[Cv];

WhileStatement.prototype[Cv] = IfStatement.prototype[Cv];

ForStatement.prototype[Cv] = IfStatement.prototype[Cv];

ForVarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    var init = (new VarStatement([], this.decls))[Cv](add_vars, add_decls);
    if ( init instanceof EmptyStatement ) {
        init = null;
    } else {
        init = init.exp;
    }
    return new ForStatement(this.labels, init, this.cond, this.incr, this.body[Cv](add_vars, add_decls), this.lineno, this.source);
};

ForInStatement.prototype[Cv] = IfStatement.prototype[Cv];

ForInVarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    add_vars(this.decl.id);
    var for_in = new ForInStatement(this.labels, this.decl.id, this.exp, this.body[Cv](add_vars, add_decls), this.lineno, this.source);
    if ( this.decl.exp ) {
        return new Block([], list(
            new ExpStatement([], new SimpleAssignExpression(this.decl.id, this.decl.exp), this.lineno, this.source),
            for_in
        ), this.lineno, this.source);
    } else {
        return for_in;
    }
};

ForEachStatement.prototype[Cv] = IfStatement.prototype[Cv];

ForEachVarStatement.prototype[Cv] = ForInVarStatement.prototype[Cv];

WithStatement.prototype[Cv] = IfStatement.prototype[Cv];

SwitchStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    for ( var c=this.clauses;  !c.isNil();  c=c.cdr ) {
        c.car = c.car[Cv](add_vars, add_decls);
    }
    return this;
};

CaseClause.prototype[Cv] = Block.prototype[Cv];

DefaultClause.prototype[Cv] = Block.prototype[Cv];

TryCatchStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    add_vars(this.variable);
    this.tryBlock   = this.tryBlock[Cv](add_vars, add_decls);
    this.catchBlock = this.catchBlock[Cv](add_vars, add_decls);
    return this;
};

TryFinallyStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    this.tryBlock     = this.tryBlock[Cv](add_vars, add_decls);
    this.finallyBlock = this.finallyBlock[Cv](add_vars, add_decls);
    return this;
};

TryCatchFinallyStatement.prototype[Cv] = function ( add_vars, add_decls ) {
    add_vars(this.variable);
    this.tryBlock     = this.tryBlock[Cv](add_vars, add_decls);
    this.catchBlock   = this.catchBlock[Cv](add_vars, add_decls);
    this.finallyBlock = this.finallyBlock[Cv](add_vars, add_decls);
    return this;
};

FunctionDeclaration.prototype[Cv] = function ( add_vars, add_decls ) {
    add_vars(this.name);
    add_decls( new ExpStatement(
        [],
        new SimpleAssignExpression(
            this.name,
            new FunctionExpression(null, this.params, this.body)
        ),
        this.lineno,
        this.source
    ));
    return new EmptyStatement([]);
};

            return {
                CvConvert: CvConvert
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CvConvert = CvConvert;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( this.Concurrent.Thread.Compiler.CzConvert === undefined ) this.Concurrent.Thread.Compiler.CzConvert = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread.Compiler';

var IL = Concurrent.Thread.Compiler.IntermediateLanguage;

var Cz = "$Concurrent_Thread_Compiler_CzConvert";

var PREFIX   = "$Concurrent_Thread_";
var var_this = new Identifier(PREFIX+"this");
var var_args = new Identifier(PREFIX+"arguments");
var var_cont = new Identifier(PREFIX+"continuation");
var var_self = new Identifier(PREFIX+"self");
var var_compiled     = new Identifier(PREFIX+"compiled");
var var_intermediate = new Identifier(PREFIX+"intermediate");

var name_arguments = new Identifier("arguments");
var name_prototype = new Identifier("prototype");
var name_apply     = new Identifier("apply");
var name_procedure = new Identifier("procedure");
var name_this_val  = new Identifier("this_val");
var name_exception = new Identifier("exception");

var var_null_function = new Identifier(PREFIX+"null_function");
var null_function = new FunctionDeclaration([], var_null_function, [], nil());

function CzConvert ( func ) {
    var body = inner_function(func);
    return new FunctionExpression(
               null,
               [var_this, var_args, var_cont],
               list(
                   new ReturnStatement([],
                       new CallExpression(
                           new DotAccessor(body, name_apply),
                           [var_this, var_args]
                       )
                   )
               )
           );
}

var arguments_callee = new DotAccessor(name_arguments, new Identifier("callee"));

function inner_function ( func ) {
    var blocks = func.body.map(function(it){ return it[Cz](); });
    blocks = cons( var_declaration(func.vars),
             cons( null_function,
             cons( make_assign(var_args, name_arguments),
             cons( make_assign(arguments_callee, var_self),
                   blocks ) ) ) );
    adder(blocks)( make_return(func.start) );
    return new FunctionExpression(null, func.params, blocks);
}

function var_declaration ( vars ) {
    if ( !vars.length ) return new EmptyStatement([]);
    var decls = [];
    vars.forEach(function( it ){
        decls.push({ id:it, exp:null });
    });
    return new VarStatement([], decls);
}

function make_assign ( lhs, rhs ) {
    return new ExpStatement( [], new SimpleAssignExpression(lhs, rhs) );
}

var var_cont_ex = new DotAccessor(var_cont, name_exception);

function target_to_name ( b ) {
    if ( b instanceof IL.Block ) {
        return new Identifier(PREFIX + b.id);
    } else if ( b === "return" ) {
        return var_cont;
    } else if ( b === "throw" ) {
        return var_cont_ex;
    } else {
        Kit.codeBug("invalid target");
    }
}

var undefinedExp = new VoidExpression(new Literal(0));
var name_continuation = new Identifier("continuation");
var name_timeout      = new Identifier("timeout");
var name_ret_val      = new Identifier("ret_val");

function make_return ( continuation, ret_val ) {
    return new ReturnStatement([], new ObjectInitializer([
               { prop: name_continuation, exp: target_to_name(continuation) },
               { prop: name_ret_val     , exp: ret_val || undefinedExp },
               { prop: name_timeout     , exp: undefinedExp            }
           ]) );
}

var assign_arguments = make_assign(name_arguments, var_args);

function make_continuation ( block, body ) {
    body = new Block([], body);
    for ( var i=block.scopes.length-1;  i >= 0;  i-- ) {
        body = new WithStatement([], block.scopes[i], body);
    }
    return new VarStatement([], [{
        id : target_to_name(block),
        exp: new ObjectInitializer([
                 {prop: name_procedure, exp: new FunctionExpression(null, [var_intermediate], list(assign_arguments, body))},
                 {prop: name_this_val , exp: new ThisExpression() },
                 {prop: name_exception, exp: target_to_name(block.exception) }
             ])
    }]);
}

IL.GotoBlock.prototype[Cz] = function ( ) {
    var body = this.body.map(function( it ) {
        return it[Cz]();
    });
    body = cons(null, body);
    adder(body)( make_return(this.target, this.arg) );
    return make_continuation(this, body.cdr);
};

var string_object   = new StringLiteral('"object"');
var string_function = new StringLiteral('"function"');

IL.CallBlock.prototype[Cz] = function ( ) {
    var body = this.body.map(function( it ) {
        return it[Cz]();
    });
    body = cons(null, body);
    adder(body)( new IfElseStatement([],
        new AndExpression(
            this.func,
            new StrictEqualExpression(
                new TypeofExpression(
                    new DotAccessor(this.func, var_compiled)
                ),
                string_function
            )
        ),
        new ReturnStatement([],
            new CallExpression(
                new DotAccessor(this.func, var_compiled),
                [
                    this.this_val,
                    new ArrayInitializer(this.args),
                    target_to_name(this.target)
                ]
            )
        ),
        make_return(
            this.target,
            new CallExpression(this.func, this.args)
        )
    ) );
    return make_continuation(this, body.cdr);
};

IL.NewBlock.prototype[Cz] = function ( ) {
    var body = this.body.map(function( it ) {
        return it[Cz]();
    });
    body = cons(null, body);
    /*  // Construct the following code-tree.
        if ( CONSTRUCTOR && typeof CONSTRUCTOR.$Concurrent_Thread_compiled == "function" ) {
        $Concurrent_Thread_null_function.prototype = CONSTRUCTOR.prototype;
        $Concurrent_Thread_this = new $Concurrent_Thread_null_function();
        return CONSTRUCTOR.$Concurrent_Thread_compiled(
                   $Concurrent_Thread_this,
                   [ARG1, ARG2, ...],
                   { procedure: function($Concurrent_Thread_intermediate){
                    if ( !($Concurrent_Thread_intermediate && (typeof $Concurrent_Thread_intermediate === "object" || typeof $Concurrent_Thread_intermediate === "function") )
                      $Concurrent_Thread_intermediate = $Concurrent_Thread_this;
                    $Concurrent_Thread_this = null;  // encourages GC
                       return { continuation: CONTINUATION,
                                ret_val     : $Concurrent_Thread_intermediate,
                                timeout     : void 0                          };
                   }, this_val: this, exception: EXCEPTION }
               );
        } else {
            return { continuation: CONTINUATION,
                     ret_val     : new CONSTRUCTOR(ARG1, ARG2...),
                     timeout     : void 0
                   };
        }
     */
    adder(body)( new IfElseStatement([],
        new AndExpression(
            this.func,
            new StrictEqualExpression(
                new TypeofExpression(
                    new DotAccessor(this.func, var_compiled)
                ),
                string_function
            )
        ),
        new Block([],
            list(
                make_assign( new DotAccessor(var_null_function, name_prototype),
                             new DotAccessor(this.func        , name_prototype) ),
                make_assign( var_this, new NewExpression(var_null_function, []) ),
                new ReturnStatement([],
                    new CallExpression(
                        new DotAccessor(this.func, var_compiled),
                        [
                            var_this,
                            new ArrayInitializer(this.args),
                            new ObjectInitializer([
                                {prop: name_procedure, exp: new FunctionExpression(null, [var_intermediate], list(
                                    new IfStatement([],
                                        new NotExpression(
                                            new AndExpression(
                                                var_intermediate,
                                                new OrExpression(
                                                    new StrictEqualExpression(new TypeofExpression(var_intermediate), string_object),
                                                    new StrictEqualExpression(new TypeofExpression(var_intermediate), string_function)
                                                )
                                            )
                                        ),
                                        make_assign(var_intermediate, var_this)
                                    ),
                                    make_assign(var_this, new NullLiteral()),
                                    make_return(this.target, var_intermediate)
                                ))},
                                {prop: name_this_val , exp: new ThisExpression()},
                                {prop: name_exception, exp: target_to_name(this.exception)}
                             ])
                        ]
                    )
                )
            )
        ),
        make_return(this.target, new NewExpression(this.func, this.args))
    ) );
    return make_continuation(this, body.cdr);
};

IL.ExpStatement.prototype[Cz] = function ( ) {
    return new ExpStatement([], this.exp);
};

IL.CondStatement.prototype[Cz] = function ( ) {
    return new IfStatement([], this.cond, make_return(this.target));
};

IL.RecvStatement.prototype[Cz] = function ( ) {
    return make_assign(this.assignee, var_intermediate);
};

var name_push = new Identifier("push");

IL.EnumStatement.prototype[Cz] = function ( ) {
    return new Block([], list(
        make_assign(var_this, new ArrayInitializer([])),
        new ForInStatement([], var_intermediate, this.exp,
            new ExpStatement([],
                new CallExpression(
                    new DotAccessor(var_this, name_push),
                    [var_intermediate]
                )
            )
        ),
        make_assign(this.assignee, var_this),
        make_assign(var_this, new NullLiteral())
    ));
};

            return {
                CzConvert: CzConvert
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.Compiler.CzConvert = CzConvert;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( this.Concurrent.Thread.compile === undefined ) this.Concurrent.Thread.compile = undefined;
    if ( this.Concurrent.Thread.CACHE_LIMIT === undefined ) this.Concurrent.Thread.CACHE_LIMIT = undefined;
    if ( this.Concurrent.Thread.prepare === undefined ) this.Concurrent.Thread.prepare = undefined;
    if ( this.Concurrent.Thread.prepareTree === undefined ) this.Concurrent.Thread.prepareTree = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {
with ( Concurrent.Thread ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread code.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2006-2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread';

var IL = Concurrent.Thread.Compiler.IntermediateLanguage;

var PREFIX            = "$Concurrent_Thread_";
var var_self     = new Identifier(PREFIX + "self");
var var_compiled = new Identifier(PREFIX + "compiled");

function compile ( f ) {
    return eval(prepare(f));
}

CACHE_LIMIT = 50;
var prepare_cache = {};
var cache_history = [];

function prepare ( f ) {
    if ( typeof f != "function" ) throw new TypeError("argument must be a function");
    f = f.toString();
    var c = prepare_cache[f];
    if ( c ) return c;
    c = prepareTree(parseFunction(f)).toString();
    while ( cache_history.length >= CACHE_LIMIT  &&  cache_history.length > 0 ) {  // avoid endless loop
        delete prepare_cache[cache_history.shift()];
    }
    if ( CACHE_LIMIT >= 1 ) {
        prepare_cache[f] = c;
        cache_history.push(f);
    }
    return c;
}

function parseFunction ( f ) {
    var stmts = (new Parser()).parse("(" + f + ");");
    if ( !(stmts.car instanceof ExpStatement) ) throw new Error("not exp-statement!");
    if ( !(stmts.car.exp instanceof FunctionExpression) ) throw new Error("not function-expression!");
    return stmts.car.exp;
}

function prepareTree ( f ) {
    if ( !(f instanceof FunctionExpression) ) Kit.codeBug("not FunctionalExpression");
    var name = f.name;
    f.name = null;
    var g = CssConvert(f);
    g = CvConvert(g);
    g = CsConvert(g);
    g = CfConvert(g);
    g = CzConvert(g);
    return new CallExpression(
        new FunctionExpression(null, [], list(
            new VarStatement([], [{id:var_self, exp:f}]),
            name ? new VarStatement([], [{id:name, exp:var_self}]) : new EmptyStatement([]),
            new ExpStatement([], new SimpleAssignExpression(new DotAccessor(var_self, var_compiled), g)),
            new ReturnStatement([], var_self)
        )),
        []
    );
    /* Constructs the following structure:
        "(function(){",
        "  var $Concurrent_Thread_self = ", f, ";",
        name  ?  "var " + name + " = " + "$Concurrent_Thread_self;"  :  "",
        "  $Concurrent_Thread_self.$Concurrent_Thread_compiled = ", func, ";",
        "  return $Concurrent_Thread_self;",
        "})()"
    */
}

            return {
                compile: compile, prepareTree: prepareTree, prepare: prepare
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.compile = compile;
    this.Concurrent.Thread.prepareTree = prepareTree;
    this.Concurrent.Thread.prepare = prepare;
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
with ( function(){
with ( Concurrent.Thread.Compiler ) {

        return function () {
            var VERSION ;
            var NAMESPACE;

NAMESPACE = 'Concurrent.Thread.Compiler';

WebBrowser.ScriptExecuter.register("text/x-script.multithreaded-js", function ( src ){
    eval(compile(src)).async(null);
});

function compile ( src ) {
    var prog = (new Parser).parse(src);
    prog = new FunctionExpression(null, [], prog);
    prog = CssConvert(prog);
    prog = CvConvert(prog);
    prog = CsConvert(prog);
    prog = CfConvert(prog);
    prog.vars.forEach(function( it ){
        // Incredibly, window does not have hasOwnProperty method on IE!!
        if ( !Object.prototype.hasOwnProperty.call(window, it) ) window[it] = undefined;
    });
    prog.vars = [];
    prog = CzConvert(prog);
    return [
        "1, function(){",
        "    var $Concurrent_Thread_self = function(){};",
        "    $Concurrent_Thread_self.$Concurrent_Thread_compiled = ", prog, ";",
        "    return $Concurrent_Thread_self;",
        "}()"
    ].join("");
}

            return {

            };
        }();
    }
}.call(null) ) {
}
}).call(null);
(function(){
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Continuation || (typeof this.Concurrent.Thread.Continuation != 'object' && typeof this.Concurrent.Thread.Continuation != 'function') ) this.Concurrent.Thread.Continuation = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( this.Concurrent.Thread.Generator === undefined ) this.Concurrent.Thread.Generator = undefined;
with ( function(){
with ( Concurrent.Thread.Continuation ) {
with ( Concurrent ) {
with ( Concurrent.Thread ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Concurrent.Thread.Generator module.
 *
 * The Initial Developer of the Original Code is
 * Daisuke Maki.
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

NAMESPACE = 'Concurrent.Thread';

function Generator ( f ) {
    if ( typeof f != "function" ) throw new TypeError("not a function");
    if ( typeof f.$Concurrent_Thread_compiled != "function" ) f = Thread.compile(f);
    this._mutex       = new Mutex();
    this._cont_caller = null;
    this._buf         = null;
    this._got         = false;

    var self = this;

    var generate = eval(Thread.prepare(function( x ){
        self._buf = x;
        self._got = true;
        try {
            self._cont_iter = currentContinuation();
            self._cont_caller();
        } catch ( e ) {
            self._cont_iter = null;
            if ( e instanceof ContinuationCalledException ) {
                return;  // resume iteration
            } else {
                throw e;
            }
        }
        // execution never reaches here
    }));

    this._cont_iter = eval(Thread.prepare(function(){
        f(generate);
        self._got       = false;
        self._cont_iter = null;  // null means that the iteration function has finished
        self._cont_caller();
    }));
}

var proto = Generator.prototype;

proto.hasNext = function ( ) {
    // This definition is called when generator is used in non-converted context.
    // The implementation is quite tricky and strongly dependent on the internal
    // implementation of Concurrent.Thread.

    if ( !this._mutex.isAcquirable() ) this._mutex.acquire();  // must throw an error
    if ( this._got            ) return true;
    if ( !this._cont_iter     ) return false;

    var is_called = false;
    this._cont_caller = eval(Thread.prepare(function(){
        is_called = true;
        Thread.stop();
    }));

    var triplet = Thread.create(this._cont_iter)._triplet;
    triplet.timeout = void 0;
    while ( 1 ) {
        while ( triplet.timeout === void 0 ) {
            try {
                triplet = triplet.continuation.procedure.call(
                              triplet.continuation.this_val, triplet.ret_val
                         );
            } catch ( e ) {
                if ( e instanceof NoContinuationException ) {
                    return this._got;
                } else if ( e instanceof NoExceptionHandlerException ) {
                    throw e.thrown;
                } else {
                    triplet.continuation = triplet.continuation.exception;
                    triplet.ret_val      = e;
                }
            }
        }
        if ( is_called ) {
            break;
        } else {
            triplet.continuation = triplet.continuation.exception;
            triplet.ret_val      = new Error("can't suspend in non-converted context");
        }
    }
    this._cont_caller = null;
    return this._got;
};

proto.hasNext.$Concurrent_Thread_compiled = eval(Thread.prepare(
    function ( ) {
        this._mutex.acquire();
        try {
            if ( this._got        ) return true;
            if ( !this._cont_iter ) return false;
            try {
                this._cont_caller = currentContinuation();
                this._cont_iter();
            } catch ( e ) {
                this._cont_caller = null;
                if ( e instanceof ContinuationCalledException ) {
                    return this._got;
                } else {
                    throw e;
                }
            }
        } finally {
            this._mutex.release();
        }
        // execution never reaches here
    }
)).$Concurrent_Thread_compiled;

proto.next = eval(Thread.prepare(
    function ( ) {
        if ( this.hasNext() ) {
            var x = this._buf;
            this._buf = void 0;
            this._got = false;
            return x;
        } else {
            return void 0;
        }
    }
));

            return {
                Generator: Generator
            };
        }();
    }
}
}
}.call(null) ) {
    this.Concurrent.Thread.Generator = Generator;
}
}).call(null);
(function(){
    if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
    if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.JSON || (typeof this.Concurrent.Thread.JSON != 'object' && typeof this.Concurrent.Thread.JSON != 'function') ) this.Concurrent.Thread.JSON = new Object();
    if ( !this.Concurrent.Thread.JSON.RPC || (typeof this.Concurrent.Thread.JSON.RPC != 'object' && typeof this.Concurrent.Thread.JSON.RPC != 'function') ) this.Concurrent.Thread.JSON.RPC = new Object();
    if ( !this.JSON || (typeof this.JSON != 'object' && typeof this.JSON != 'function') ) this.JSON = new Object();
    if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
    if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
    if ( this.Concurrent.Thread.JSON.RPC.bind === undefined ) this.Concurrent.Thread.JSON.RPC.bind = undefined;
    if ( this.Concurrent.Thread.JSON.RPC.JSONRPCError === undefined ) this.Concurrent.Thread.JSON.RPC.JSONRPCError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Util.Arrayize ) {
with ( JSON ) {
with ( Concurrent ) {
with ( Concurrent.Thread.JSON.RPC ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

NAMESPACE = 'Concurrent.Thread.JSON.RPC';

function bind ( opts ) {
    if ( !(opts instanceof Object) ) throw new TypeError("argument for " + NAMESPACE + ".bind must be a hash.");
    var request = opts.request;
    if ( request != null ) {
        if ( !String(request).match(/^(?:GET|POST)$/i) ) throw new Error('"request" option must be "GET" or "POST".');
    } else {
        request = "POST";
    }
    var params = opts.params;
    if ( params != null ) {
        if ( !String(params).match(/^(?:Named|Positioned)$/i) ) throw new Error('"params" option must be "Named" or "Positioned".');
    } else {
        params = "Named";
    }
    var body;
    if ( request.match(/^POST$/i) ) {
        if ( params.match(/^Named$/i) ) {
            body = makeNamedPost(opts.url, opts.method);
        } else {
            body = makePositionedPost(opts.url, opts.method);
        }
    } else {
        if ( params.match(/^Named$/i) ) {
            body = makeNamedGet(opts.url, opts.method);
        } else {
            body = makePositionedGet(opts.url, opts.method);
        }
    }
    var with_pre;
    var pre = opts.preprocess;
    if ( pre != null ) {
        if ( typeof pre != "function" ) throw new TypeError('"preprocess" option must be function');
        with_pre = eval(Thread.prepare(function(){
            return body.apply(this, pre.apply(this, arguments));
        }));
    } else {
        with_pre = body;
    }
    var post = opts.postprocess;
    if ( post != null ) {
        if ( typeof post != "function" ) throw new TypeError('"preprocess" option must be function');
        return eval(Thread.prepare(function(){
            return post(with_pre.apply(this, arguments));
        }));
    } else {
        return with_pre;
    }
}

var COMMON_HEADERS = [
    'User-Agent'  , 'Concurrent.Thread.JSON.RPC',
    'Accept'      , 'application/json'
];

var POST_HEADERS = COMMON_HEADERS.concat(
    'Content-type', 'application/json'
);

function makeNamedPost( url, method ) {
    return eval(Thread.prepare(
        function ( /* variable arguments */ ) {
            var res = Thread.Http.post(url, dump({
                version: "1.1",
                method : method,
                params : args2params(arguments)
            }), POST_HEADERS);
            res = eval("(" + res.responseText + ")");
            if ( res.error ) throw new JSONRPCError(res.error);
            return res.result;
        }
    ));
};

function makePositionedPost ( url, method ) {
    return eval(Thread.prepare(
        function ( /* variable arguments */ ) {
            var res = Thread.Http.post(url, dump({
                version: "1.1",
                method : method,
                params : arrayize(arguments)
            }), POST_HEADERS);
            res = eval("(" + res.responseText + ")");
            if ( res.error ) throw new JSONRPCError(res.error);
            return res.result;
        }
    ));
};

function makeNamedGet ( url, method ) {
    url = url.replace(/\/+$/, "") + "/" + encodeURIComponent(method) + "?";
    return eval(Thread.prepare(
        function ( /* variable arguments */ ) {
            var res = Thread.Http.get(url + params2query(args2params(arguments)), COMMON_HEADERS);
            res = eval("(" + res.responseText + ")");
            if ( res.error ) throw new JSONRPCError(res.error);
            return res.result;
        }
    ));
};

function makePositionedGet ( url, method ) {
    url = url.replace(/\/+$/, "") + "/" + encodeURIComponent(method) + "?";
    return eval(Thread.prepare(
        function ( /* variable arguments */ ) {
            arguments[arguments.length] = {};
            arguments.length++;
            var res = Thread.Http.get(url + params2query(args2params(arguments)), COMMON_HEADERS);
            res = eval("(" + res.responseText + ")");
            if ( res.error ) throw new JSONRPCError(res.error);
            return res.result;
        }
    ));
};

function args2params ( args ) {
    var params = {};
    if ( args.length ) {
        var hash = args[args.length-1];
        if ( !(hash instanceof Object) ) throw new Error("the last argument must be a hash");
        for ( var i in hash ) {
            if ( hash.hasOwnProperty(i) ) params[i] = hash[i];
        }
        for ( var i=0;  i < args.length-1;  i++ ) {
            params[i] = args[i];
        }
    }
    return params;
}

function params2query ( params ) {
    var query = [];
    for ( var i in params ) {
        if ( !params.hasOwnProperty(i) ) continue;
        if ( params[i] instanceof Array ) {
            var arr = params[i];
            for ( var j=0;  j < arr.length;  j++ ) {
                query.push(encodeURIComponent(i) + "=" + encodeURIComponent(arr[j]));
            }
        } else {
            query.push(encodeURIComponent(i) + "=" + encodeURIComponent(params[i]));
        }
    }
    return query.join("&");
}

var JSONRPCError = Error.extend(
    function ( $super, e ) {
        if ( e instanceof Object ) {
            $super(e.message);
            for ( var i in e ) this[i] = e[i];
        } else {
            $super(e);
        }
    },
    {name: NAMESPACE + ".JSONRPCError"}
);

            return {
                JSONRPCError: JSONRPCError, bind: bind
            };
        }();
    }
}
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.JSON.RPC.JSONRPCError = JSONRPCError;
    this.Concurrent.Thread.JSON.RPC.bind = bind;
}
}).call(null);
(function(){
    if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
    if ( !this.WebBrowser.GUI || (typeof this.WebBrowser.GUI != 'object' && typeof this.WebBrowser.GUI != 'function') ) this.WebBrowser.GUI = new Object();
    if ( !this.WebBrowser.GUI.Event || (typeof this.WebBrowser.GUI.Event != 'object' && typeof this.WebBrowser.GUI.Event != 'function') ) this.WebBrowser.GUI.Event = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
    if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
    if ( !this.Concurrent.Thread.Event || (typeof this.Concurrent.Thread.Event != 'object' && typeof this.Concurrent.Thread.Event != 'function') ) this.Concurrent.Thread.Event = new Object();
    if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
    if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
    if ( this.Concurrent.Thread.Event.waitFor === undefined ) this.Concurrent.Thread.Event.waitFor = undefined;
    if ( this.Concurrent.Thread.Event.select === undefined ) this.Concurrent.Thread.Event.select = undefined;
with ( function(){
with ( Util.Arrayize ) {
with ( WebBrowser.GUI.Event ) {
with ( Concurrent ) {
with ( Concurrent.Thread.Event ) {

        return function () {
            var VERSION = '0.0.0';
            var NAMESPACE;

NAMESPACE = 'Concurrent.Thread.Event';

var waitFor = eval(Concurrent.Thread.prepare(
    function waitFor ( target, type, options ) {
        var arg = {};
        for ( var i in options ) arg[i] = options[i];
        arg.target = target;
        arg.type   = type;
        return select(arg);
    }
));

var select = eval(Concurrent.Thread.prepare(
    function select ( /* variable args */ ) {
        try {
            var signal = {};
            set_handlers(arrayize(arguments), signal);
            Concurrent.Thread.stop();
        } catch ( e ) {
            if ( e === signal ) {
                return signal.event;
            } else {
                throw e;
            }
        }
    }
));

function set_handlers ( args, signal ) {
    var self = Concurrent.Thread.self();

    args = args.map(function( arg ){
        if ( !arg.target || typeof arg.target !== "object" ) {
            throw new TypeError("not a object: " + target);
        }
        return {
            target         : arg.target,
            type           : String(arg.type),
            useCapture     : Boolean(arg.useCapture),
            preventDefault : Boolean(arg.preventDefault),
            stopPropagation: Boolean(arg.stopPropagation)
        };
    });

    var lsn_ids = args.map(function( arg ){
        function handler ( e ) {
            if ( arg.preventDefault  ) e.preventDefault();
            if ( arg.stopPropagation ) e.stopPropagation();
            lsn_ids.forEach(function( id ){
                detach(id);
            });
            // IE invalidates event properties after leaving the event handler.
            // So, we pass a copy of the current event object (but DO NOT copy its methods).
            var evt = {};
            for ( var i in e ) {
                if ( typeof e[i] !== "function" ) evt[i] = e[i];
            }
            signal.event  = evt;
            self.notify(signal);
        }
        return attach(arg.target, arg.type, handler, arg.useCapture);
    });
}

            return {
                waitFor: waitFor, select: select
            };
        }();
    }
}
}
}
}.call(null) ) {
    this.Concurrent.Thread.Event.waitFor = waitFor;
    this.Concurrent.Thread.Event.select = select;
}
}).call(null);

  

Concurrent.Thread.js的更多相关文章

  1. JavaScript 编写多线程代码引用Concurrent.Thread.js(转)

    这是一个很简单的功能实现: <script type="text/javascript" src="Concurrent.Thread.js">&l ...

  2. JavaScript 编写线程代码引用Concurrent.Thread.js

    马上来下载和使用源码吧!假定你已经将下载的源码保存到一个名为Concurrent.Thread.js的文件夹里,在进行任何操作之前,先运行如下程序,这是一个很简单的功能实现: <script t ...

  3. 【转】《高级前端3.6》JavaScript多线程——Concurrent.Thread.js, WebWork

    原文链接:http://www.cnblogs.com/woodk/articles/5199536.html JavaScript多线程,在HTML5 WebWork没出现之前很多人都是用Concu ...

  4. javascript实现多线程 Concurrent.Thread.js

    在这次我的项目中,因为前端要检测硬件加载并识别,再向后台请求发送数据,然后再返回的相应的配置文件!在这过程,要好时好几秒钟,严重影响体验效果,所以在网上靠看的方案,运用多线程去处理,这效果明显改善! ...

  5. JS多线程(web work)

    JS多线程JS多线程不允许操作DOM 1. 引用Concurrent Thread.js库用法:Concurrent.Thread.Create(function(){};) 2. Web Workh ...

  6. JS的多线程

    注:以下内容基于IE中GIF的onload事件的基础上,故所有测试IE only 需要用到的几个图片 先看一个简单的事实: 复制代码代码如下: <SCRIPT LANGUAGE="Ja ...

  7. [JS] JavaScript由浅入深(2) 进阶

    本节,将围绕以下几点来讲. 知识点:多线程.作用域.闭包.this 先顶后看 1.多线程 在不支持H5的浏览器中.使用Concurrent.Thread.js. 在支持H5中,使用WebWork. 在 ...

  8. 你所不了解的setTimeout

    看到了一篇不错的文章<你会用setTimeout吗 >,转载过来的,改了个名字,一下子感觉搞大上了,嘎嘎. 加了几个关于 setTimeout 和setInterval的小知识: 关于se ...

  9. javascript多线程简介

    讲多线程之前,我们先了解一下JS的事件机制 浏览器运行时,脚本必须定期让位给UI进程进行来维持网页的响应,闲置太长时间的脚本可能会被浏览器当成失控脚本,进而造成假死或弹窗 事件触发的设计javascr ...

随机推荐

  1. C语言回调

    来源:https://www.cnblogs.com/jiangzhaowei/p/9129105.html 1. 什么是回调函数? 回调函数,光听名字就比普通函数要高大上一些,那到底什么是回调函数呢 ...

  2. 洛谷 P2738 [USACO4.1]篱笆回路Fence Loops

    P2738 [USACO4.1]篱笆回路Fence Loops 题目描述 农夫布朗的牧场上的篱笆已经失去控制了.它们分成了1~200英尺长的线段.只有在线段的端点处才能连接两个线段,有时给定的一个端点 ...

  3. [Angular] Configure an Angular App at Compile Time with the Angular CLI

    Compile time configuration options allow you to provide different kind of settings based on the envi ...

  4. Unity 相机花式分屏

    花式分屏,顾名思义,可以实现各种不规则几何边界的分屏,是无法直接通过调整相机视口能达到效果的(只能实现矩形的分屏),例如斜对角分屏,几何图形分屏: 假设我们有两个相机,需要上面的斜对角分屏画面,和镜子 ...

  5. 【CTO辩论会】移动开发人员忠于技术or 背离技术

    第一期CTO辩论会结束后,大家在微信群中讨论,学什么编程语言好.有位官人直呼"劳力者治于人,苦差,不学也罢". 在IT.科技变革世界的今天,移动开发人员成为一个很时髦的工种. 就连 ...

  6. cocos2dx下的A星算法

    这是我依据这篇博文http://hi.baidu.com/wsapyoemdfacmqr/item/bdfb5c0a74c904d01ef0466d.来在cocos2dx上编写.这是终于的效果图: 红 ...

  7. FZOJ--2212--Super Mobile Charger(水题)

    Problem 2212 Super Mobile Charger Accept: 3    Submit: 11 Time Limit: 1000 mSec    Memory Limit : 32 ...

  8. BZOJ 球形空间产生器 解题报告(高斯消元)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1013 1013: [JSOI2008]球形空间产生器sphere 有一个球形空间产生器能 ...

  9. java根据模板导出PDF(利用itext)

    一.制作模板     1.下载Adobe Acrobat 9 Pro软件(pdf编辑器),制作模板必须使用该工具. 2.下载itextpdf-5.5.5.jar.itext-asian-5.2.0.j ...

  10. button click event in jqxgrid jqwidgets

    button click event in jqxgrid jqwidgets http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/p ...