/*====================================================
 * rapl_Base.js "A Tcl like language implementation in Javascript named WebRAPL 
 * (Web Rapid Application Programming Language)"
 *
 * Base of RAPL 
 *
 * Released under BSD license.
 * (BSD license found at <http://www.tcl.tk/software/tcltk/license.html>)
 *
 * Arnulf Wiedemann    2011
 */

RP.add("rapl-base", function(R, name) {

  function Base() {
    R.log('constructor called', '2.life', 'base', true);

    var base = this;
    base.name = base.constructor.NAME;
    base.init.apply(base, arguments);

    R.log('constructor end', '2.life', 'base', true);
  }

  Base.parser_oid = 0;
  Base.meta_oid = 0;
  Base.variable_oid = 0;
  Base.command_oid = 0;
  Base.resolved_cmd_name_oid = 0;
  Base.itcl_command_oid = 0;
  Base.class_function_oid = 0;
  Base.call_frame_oid = 0;
  Base.namespace_oid = 0;
  Base.interp_oid = 0;
  Base.object_oid = 0;
  Base.script_oid = 0;
  Base.variable_oid = 0;
  Base.oid = 0;
  Base.array_obj_type_oid = 0;
  Base.coerced_double_obj_type_oid = 0;
  Base.command_obj_type_oid = 0;
  Base.compared_string_obj_type_oid = 0;
  Base.dict_obj_type_oid = 0;
  Base.double_obj_type_oid = 0;
  Base.expr_obj_type_oid = 0;
  Base.index_obj_type_oid = 0;
  Base.int_obj_type_oid = 0;
  Base.interpolated_obj_type_oid = 0;
  Base.itcl_obj_type_oid = 0;
  Base.list_obj_type_oid = 0;
  Base.local_var_name_obj_type_oid = 0;
  Base.namespace_var_name_obj_type_oid = 0;
  Base.package_obj_type_oid = 0;
  Base.param_obj_type_oid = 0;
  Base.parsed_var_name_obj_type_oid = 0;
  Base.reference_obj_type_oid = 0;
  Base.regexp_obj_type_oid = 0;
  Base.return_code_obj_type_oid = 0;
  Base.scan_fmt_string_obj_type_oid = 0;
  Base.script_line_obj_type_oid = 0;
  Base.script_obj_type_oid = 0;
  Base.string_obj_type_oid = 0;
  Base.source_obj_type_oid = 0;
  Base.variable_obj_type_oid = 0;
  Base.expr_oid = 0;
  Base.itcl_class_oid = 0;
  Base.itcl_object_oid = 0;
  Base.itcl_function_oid = 0;
  Base.itcl_variable_oid = 0;
  Base.itcl_option_oid = 0;
  Base.itcl_delegate_oid = 0;
  Base.itcl_component_oid = 0;
  Base.itcl_variable_lookup_oid = 0;
  Base.parse_token_info_oid = 0;
  Base.token_info_oid = 0;
  Base.package_info_oid = 0;
  Base.function_arg_list_oid = 0;
  Base.function_arg_oid = 0;
  Base.test_case_oid = 0;
  Base.tcltest_oid = 0;
  Base.trace_oid = 0;
  Base.resolve_oid = 0;
  Base.tk_standard_option_oid = 0;
  Base.tk_option_base_oid = 0;
  Base.test_result_oid = 0;
  Base.pkg_core_oid = 0;
  Base.pkg_list_oid = 0;
  Base.pkg_namespace_oid = 0;
  Base.pkg_dict_oid = 0;
  Base.pkg_string_oid = 0;
  Base.pkg_package_oid = 0;
  Base.pkg_info_oid = 0;
  Base.pkg_itcl_oid = 0;
  Base.pkg_tcltest_oid = 0;
  Base.pkg_trace_oid = 0;

  Base.my_name = "RaplBase";
  Base.NAME = "base";

  Base.prototype = {
    FUNCTION_FLAGS_NONE: 0,
    FUNCTION_FLAGS_LEAVE_ERR_MSG: 1,
    FUNCTION_FLAGS_UNSHARED: 2,
    FUNCTION_FLAGS_NO_CREATE: 4,
    FUNCTION_FLAGS_SUBST_NOESC: 8,
    FUNCTION_FLAGS_SUBST_NOVAR: 16,
    FUNCTION_FLAGS_SUBST_NOCMD: 32,

    functionFlags2Strings: {
      "0": "FUNCTION_FLAGS_NONE",
      "1": "FUNCTION_FLAGS_LEAVE_ERR_MSG",
      "2": "FUNCTION_FLAGS_UNSHARED",
      "4": "FUNCTION_FLAGS_NO_CREATE",
      "8": "FUNCTION_FLAGS_SUBST_NOESC",
      "16": "FUNCTION_FLAGS_SUBST_NOVAR",
      "32": "FUNCTION_FLAGS_SUBST_NOCMD"
    },

    functionFlagsStrings2function_flag: {
      "FUNCTION_FLAGS_NONE": "0",
      "FUNCTION_FLAGS_LEAVE_ERR_MSG": "1",
      "FUNCTION_FLAGS_UNSHARED": "2",
      "FUNCTION_FLAGS_NO_CREATE": "4",
      "FUNCTION_FLAGS_SUBST_NOESC": "8",
      "FUNCTION_FLAGS_SUBST_NOVAR": "16",
      "FUNCTION_FLAGS_SUBST_NOCMD": "32"
    },

    CALL_TYPE_NAMESPACE: 0,
    CALL_TYPE_PROC: 1,
    CALL_TYPE_METHOD: 2,
    CALL_TYPE_UPLEVEL: 3,
    CALL_TYPE_UPVAR: 4,
    CALL_TYPE_EVAL: 5,
    CALL_TYPE_NATIVE: 6,

    callTypes2String: {
      "0": "CALL_TYPE_NAMESPACE",
      "1": "CALL_TYPE_PROC",
      "2": "CALL_TYPE_METHOD",
      "3": "CALL_TYPE_UPLEVEL",
      "4": "CALL_TYPE_UPVAR",
      "5": "CALL_TYPE_EVAL",
      "6": "CALL_TYPE_NATIVE"
    },

    TRACE_TYPE_COMMAND: 1,
    TRACE_TYPE_EXECUTION: 2,
    TRACE_TYPE_VARIABLE: 4,

    traceTypes2String: {
      "1": "command",
      "2": "execution",
      "4": "variable"
    },

    traceTypeStrings2TraceType: {
      "command": "1",
      "execution": "2",
      "variable": "4"
    },

    TRACE_OP_DELETE: 8,
    TRACE_OP_RENAME: 16,
    TRACE_OP_ENTER: 32,
    TRACE_OP_LEAVE: 64,
    TRACE_OP_ENTERSTEP: 128,
    TRACE_OP_LEAVESTEP: 256,
    TRACE_OP_ARRAY: 512,
    TRACE_OP_READ: 1024,
    TRACE_OP_WRITE: 2048,
    TRACE_OP_UNSET: 4096,

    traceOps2String: {
      "8": "delete",
      "16": "rename",
      "32": "enter",
      "64": "leave",
      "128": "enterstep",
      "256": "leavestep",
      "512": "array",
      "1024": "read",
      "2048": "write",
      "4096": "unset"
    },

    traceOpStrings2TraceOp: {
      "delete": "8",
      "rename": "16",
      "enter": "32",
      "leave": "64",
      "enterstep": "128",
      "leavestep": "256",
      "array": "512",
      "read": "1024",
      "write": "2048",
      "unset": "4096"
    },

    PROTECTION_PUBLIC: 0,
    PROTECTION_PROTECTED: 1,
    PROTECTION_PRIVATE: 2,

    protection2String: {
      "0": "public",
      "1": "protected",
      "2": "private",
    },

    protectionStrings2Protection: {
      "public": "0",
      "protected": "1",
      "private": "2",
    },

    /* the different variable flags */
    VAR_ARRAY: 1,
    VAR_COMMON: 2,
    VAR_VARIABLE: 4,
    VAR_NAMESPACE_VAR: 8,
    VAR_TYPE_VAR: 16,
    VAR_LINK: 32,
    VAR_UNDEFINED: 64,
    VAR_LOCAL_VAR: 128,
    VAR_DICT_VAR: 256,
    VAR_THIS_VAR: 512,
    VAR_TRACED: 1024,
    VAR_DEAD_HASH: 2048,
    VAR_TRACED_READ: 4096,
    VAR_TRACED_WRITE: 8192,
    VAR_TRACED_UNSET: 16384,
    VAR_TRACED_ARRAY: 32768,
    VAR_TRACE_ACTIVE: 65536,
    VAR_SEARCH_ACTIVE: 131072,
    VAR_SELF_VAR: 262144,
    VAR_WIN_VAR: 524288,
//    VAR_ALL_TRACES: (VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_ARRAY|VAR_TRACED_UNSET),
    VAR_ALL_TRACES: 61440,

    variableTypes2String: {
      "1": "VAR_ARRAY",
      "2": "VAR_COMMON",
      "4": "VAR_VARIABLE",
      "8": "VAR_NAMESPACE_VAR",
      "16": "VAR_TYPE_VAR",
      "32": "VAR_LINK",
      "64": "VAR_UNDEFINED",
      "128": "VAR_LOCAL_VAR",
      "256": "VAR_DICT_VAR",
      "512": "VAR_THIS_VAR",
      "1024": "VAR_TRACED",
      "2048": "VAR_DEAD_HASH",
      "4096": "VAR_TRACED_READ",
      "8192": "VAR_TRACED_WRITE",
      "16384": "VAR_TRACED_UNSET",
      "32768": "VAR_TRACED_ARRAY",
      "65536": "VAR_TRACE_ACTIVE",
      "131072": "VAR_SEARCH_ACTIVE",
      "262144": "VAR_SELF_VAR",
      "524288": "VAR_WIN_VAR",
    },

    variableTypeStrings2VariableType: {
      "VAR_ARRAY": "1",
      "VAR_COMMON": "2",
      "VAR_VARIABLE": "4",
      "VAR_NAMESPACE_VAR": "8",
      "VAR_TYPE_VAR": "16",
      "VAR_LINK": "32",
      "VAR_UNDEFINED": "64",
      "VAR_LOCAL_VAR": "128",
      "VAR_DICT_VAR": "256",
      "VAR_THIS_VAR": "512",
      "VAR_TRACED": "1024",
      "VAR_DEAD_HASH": "2048",
      "VAR_TRACED_READ": "4096",
      "VAR_TRACED_WRITE": "8192",
      "VAR_TRACED_UNSET": "16384",
      "VAR_TRACED_ARRAY": "32768",
      "VAR_TRACE_ACTIVE": "65536",
      "VAR_SEARCH_ACTIVE": "131072",
      "VAR_SELF_VAR": "262144",
      "VAR_WIN_VAR": "524288",
    },

    ITCL_FUNCTION_STATE_NO_ARGS: 1,
    ITCL_FUNCTION_STATE_NO_BODY: 2,
    ITCL_FUNCTION_STATE_NO_INIT: 4,
    ITCL_FUNCTION_STATE_COMPLETE: 8,

    itclFunctionStates2String: {
      "1": "FUNCTION_STATE_NO_ARGS",
      "2": "FUNCTION_STATE_NO_BODY",
      "4": "FUNCTION_STATE_NO_INIT",
      "8": "FUNCTION_STATE_COMPLETE",
    },

    itclFunctionStateStrings2ItclFunctionState: {
      "FUNCTION_STATE_NO_ARGS": "1",
      "FUNCTION_STATE_NO_BODY": "2",
      "FUNCTION_STATE_NO_INIT": "4",
      "FUNCTION_STATE_COMPLETE": "8",
    },

    VARIABLE_STATE_NO_INIT: 1,
    VARIABLE_STATE_NO_CONFIG: 2,
    VARIABLE_STATE_COMPLETE: 4,

    itclVariableStates2String: {
      "1": "VARIABLE_STATE_NO_INIT",
      "2": "VARIABLE_STATE_NO_CONFIG",
      "4": "VARIABLE_STATE_COMPLETE",
    },

    itclVariableStateStrings2ItclVariableState: {
      "VARIABLE_STATE_NO_INIT": "1",
      "VARIABLE_STATE_NO_CONFIG": "2",
      "VARIABLE_STATE_COMPLETE": "4",
    },

    /* the different itcl class types or just a namespace */
    NAMESPACE: 1,
    ITCL_CLASS: 2,
    ITCL_EXTENDED_CLASS: 4,
    ITCL_TYPE_CLASS: 8,
    ITCL_WIDGET_CLASS: 16,
    ITCL_WIDGETADAPTOR_CLASS: 32,

    itclClassTypes2String: {
      "1": "NAMESPACE",
      "2": "class",
      "4": "extendedclass",
      "8": "typeclass",
      "16": "widget",
      "32": "widgetadaptor",
    }, 

    itclClassTypeStrings2ItclClassType: {
      "NAMESPACE": "1",
      "class": "2",
      "extendedclass": "4",
      "typeclass": "8",
      "widget": "16",
      "widgetadaptor": "32",
    }, 

    NAMESPACE_PROC: 10,
    ITCL_METHOD: 11,
    ITCL_PROC: 12,
    ITCL_TYPEMETHOD: 13,
    ITCL_CONSTRUCTOR: 14,
    ITCL_DESTRUCTOR: 15,
    ITCL_TYPECONSTRUCTOR: 16,

    itclFunctionTypes2String: {
      "10": "NAMESPACE_PROC",
      "11": "method",
      "12": "proc",
      "13": "typemethod",
      "14": "constructor",
      "15": "destructor",
      "16": "typeconstructor"
    },

    itclFunctionTypeStrings2ItclFunctionType: {
      "NAMESPACE_PROC": "10",
      "method": "11",
      "proc": "12",
      "typemethod": "13",
      "_constructor": "14",
      "_destructor": "15",
      "typeconstructor": "16"
    },

    ITCL_VARIABLE: 20,
    ITCL_COMMON: 21,
    ITCL_TYPE_VARIABLE: 22,

    itclVariableTypes2String: {
      "20": "variable",
      "21": "common",
      "22": "type_variable",
    },

    itclVariableTypeStrings2ItclVariableType: {
      "variable": "20",
      "common": "21",
      "type_variable": "22",
    },

    ITCL_OPTION: 30,
    ITCL_COMPONENT: 40,
    ITCL_YTPE_COMPONENT: 41,
    ITCL_DELEGATE: 50,
    ITCL_INHERIT: 60,

    itclOtherTypes2String: {
      "30": "option",
      "40": "component",
      "41": "typecomponent",
      "50": "delegate",
      "60": "inherit",
    },

    itclOtherTypeStrings2ItclOtherType: {
      "option": "30",
      "component": "40",
      "typecomponent": "41",
      "delegate": "50",
      "inherit": "60",
    },

    COMMAND_PROC: 1,
    COMMAND_ENSEMBLE: 2,
    COMMAND_ENSEMBLE_SUBCMD: 3,
    COMMAND_INFO_SUBCMDS: 4,
    COMMAND_JSPROC: 5,

    commandTypes2String: {
      "1": "COMMAND_PROC",
      "2": "COMMAND_ENSEMBLE",
      "3": "COMMAND_ENSEMBLE_SUBCMD",
      "4": "COMMAND_INFO_SUBCMDS",
      "5": "COMMAND_JSPROC"
    }, 

    commandTypeStrings2CommandType: {
      "COMMAND_PROC": "1",
      "COMMAND_ENSEMBLE": "2",
      "COMMAND_ENSEMBLE_SUBCMD": "3",
      "COMMAND_INFO_SUBCMDS": "4",
      "COMMAND_JSPROC": "5"
    }, 

    VAR_LOOKUP_AVOID_RESOLVERS: 8,
    VAR_LOOKUP_FOR_UPVAR: 16,

    varLookupTypes2String: {
      "8": "VAR_LOOKUP_AVOID_RESOLVERS",
      "16": "VAR_LOOKUP_FOR_UPVAR",
    },

    varLookupTypeStrings2varLookupType: {
      "VAR_LOOKUP_AVOID_RESOLVERS": 8,
      "VAR_LOOKUP_FOR_UPVAR": 16,
    },

    NAMESPACE_DYING: 64,
    NAMESPACE_DEAD: 128,
    NAMESPACE_KILLED: 256,
    NAMESPACE_LOOKUP_GLOBAL_ONLY: 512,
    NAMESPACE_LOOKUP_NAMESPACE_ONLY: 1024,
    NAMESPACE_CREATE_IF_UNKNOWN: 2048,
    NAMESPACE_FIND_ONLY: 4096,

    namespaceFlags2String: {
      "8": "VAR_LOOKUP_AVOID_RESOLVERS",
      "16": "VAR_LOOKUP_FOR_UPVAR",
      "64": "NAMESPACE_DYING",
      "128": "NAMESPACE_DEAD",
      "256": "NAMESPACE_KILLED",
      "512": "NAMESPACE_LOOKUP_GLOBAL_ONLY",
      "1024": "NAMESPACE_LOOKUP_NAMESPACE_ONLY",
      "2048": "NAMESPACE_CREATE_IF_UNKNOWN",
      "4096": "NAMESPACE_FIND_ONLY",
    },

    namespaceFlagsStrings2NamespaceFlag: {
      "NAMESPACE_DYING": "1",
      "NAMESPACE_DEAD": "2",
      "NAMESPACE_KILLED": "3",
      "NAMESPACE_LOOKUP_GLOBAL_ONLY": "64",
      "NAMESPACE_LOOKUP_NAMESPACE_ONLY": "128",
      "NAMESPACE_CREATE_IF_UNKNOWN": "512",
      "NAMESPACE_FIND_ONLY": "1024",
    },

    RESOLVER_TYPE_VARIABLE: 1,
    RESOLVER_TYPE_COMMAND: 2,

    resolverType2String: {
      "1": "RESOLVER_TYPE_VARIABLE",
      "2": "RESOLVER_TYPE_COMMAND",
    },

    resolverTypeStrings2ResolverType: {
      "RESOLVER_TYPE_VARIABLE": "1",
      "RESOLVER_TYPE_COMMAND": "2",
    },

    INTERP_DELETED: 1,
    COMMAND_DELETED: 2,

    /* =========================== init ================================== */

    /**
     * Init lifecycle method, invoked during construction.
     * Fires the init event prior to setting up attributes and 
     * invoking initializers for the class hierarchy.
     *
     * @method init
     * @chainable
     * @param {Object} config Object with configuration property name/value pairs
     * @return {Base} A reference to this object
     */
    init: function(config) {
      R.log('init called', '2.life', 'base', true);
      R.log('init end', '2.life', 'base', true);
      return this;
    },

    /* ==================== getGenericTypeString ============================== */
    getGenericTypeString: function(type_obj, msg, val) {
      var base = this;
if (typeof type_obj == "undefined") {
print("getGenericTypeString!"+msg+"!"+val+"!");
}
      if (val == null) {
        return null;
      }
      if (typeof type_obj[base.escape_key(val)] == "undefined") {
        throw msg+val+"!";
      }
      return type_obj[base.escape_key(val)];
    },

    /* ==================== getGenericTypeVal ============================== */
    getGenericTypeVal: function(type_obj, val) {
      var base = this;
if (typeof type_obj == "undefined") {
print("getGenericTypeVal!"+val+"!");
}
      if (val == null) {
        return null;
      }
      if (typeof type_obj[base.escape_key(val)] == "undefined") {
        return null;
      }
      return type_obj[base.escape_key(val)];
    },

    /* ==================== getFunctionFlagString ============================== */
    getFunctionFlagString: function(val) {
      var msg = "funny function flag: ";
      return this.getGenericTypeString(this.functionFlags2Strings, msg, val);
    },

    /* ==================== getTraceTypeString ============================== */
    getTraceTypeString: function(val) {
      var msg = "funny Trace type: ";
      return this.getGenericTypeString(this.traceTypes2String, msg, val);
    },

    /* ==================== getCallTypeString ============================== */
    getCallTypeString: function(val) {
      var msg = "funny Call type: ";
      return this.getGenericTypeString(this.callTypes2String, msg, val);
    },

    /* ==================== getTraceOpString ============================== */
    getTraceOpString: function(val) {
      var base = this;
      var msg = "funny Trace op: ";
      var str = "";
      if (val & base.TRACE_OP_DELETE) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_DELETE)+" ";
      }
      if (val & base.TRACE_OP_RENAME) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_RENAME)+" ";
      }
      if (val & base.TRACE_OP_ENTER) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_ENTER)+" ";
      }
      if (val & base.TRACE_OP_LEAVE) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_LEAVE)+" ";
      }
      if (val & base.TRACE_OP_ENTERSTEP) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_ENTERSTEP)+" ";
      }
      if (val & base.TRACE_OP_LEAVESTEP) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_LEAVESTEP)+" ";
      }
      if (val & base.TRACE_OP_ARRAY) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_ARRAY)+" ";
      }
      if (val & base.TRACE_OP_READ) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_READ)+" ";
      }
      if (val & base.TRACE_OP_WRITE) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_WRITE)+" ";
      }
      if (val & base.TRACE_OP_UNSET) {
        str += base.getGenericTypeString(base.traceOps2String, msg, base.TRACE_OP_UNSET)+" ";
      }
      return str;
    },

    /* ==================== getVariableTypeString ============================== */
    getVariableTypeString: function(val) {
      var base = this;
      var msg = "funny variable type: ";
      var str = "";
      if (val & base.VAR_ARRAY) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_ARRAY)+" ";
      }
      if (val & base.VAR_COMMON) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_COMMON)+" ";
      }
      if (val & base.VAR_VARIABLE) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_VARIABLE)+" ";
      }
      if (val & base.VAR_NAMESPACE_VAR) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_NAMESPACE_VAR)+" ";
      }
      if (val & base.VAR_TYPE_VAR) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_TYPE_VAR)+" ";
      }
      if (val & base.VAR_LINK) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_LINK)+" ";
      }
      if (val & base.VAR_UNDEFINED) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_UNDEFINED)+" ";
      }
      if (val & base.VAR_LOCAL_VAR) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_LOCAL_VAR)+" ";
      }
      if (val & base.VAR_DICT_VAR) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_DICT_VAR)+" ";
      }
      if (val & base.VAR_THIS_VAR) {
        str += base.getGenericTypeString(base.variableTypes2String, msg, base.VAR_THIS_VAR)+" ";
      }
      return str;
    },

    /* ==================== getCallTypeString ============================== */
    getCallTypeString: function(val) {
      var msg = "funny call type: ";
      return this.getGenericTypeString(this.callTypes2String, msg, val);
    },

    /* ==================== getVarLookupTypeString ============================== */
    getVarLookupTypeString: function(val) {
      var msg = "funny var_lookup type: ";
      return this.getGenericTypeString(this.varLookupTypes2String, msg, val);
    },

    /* ==================== getCommandTypeString ============================== */
    getCommandTypeString: function(val) {
      var msg = "funny command type: ";
      return this.getGenericTypeString(this.commandTypes2String, msg, val);
    },

    /* ==================== getProtectionString ============================== */
    getProtectionString: function(val) {
      var msg = "funny protection type: ";
      return this.getGenericTypeString(this.protection2String, msg, val);
    },

    /* ==================== getObjectTypeString ============================== */
    getObjectTypeString: function(val) {
      var msg = "funny object type: ";
      return this.getGenericTypeString(this.objectTypes2String, msg, val);
    },

    /* ==================== getProtectionTypeString ============================== */
    getProtectionTypeString: function(val) {
      var msg = "funny protection type: ";
      return this.getGenericTypeString(this.protectionTypes2String, msg, val);
    },

    /* ==================== getItclVariableTypeString ============================== */
    getItclVariableTypeString: function(val) {
      var msg = "funny itcl variable type: ";
      return this.getGenericTypeString(this.itclVariableTypes2String, msg, val);
    },

    /* ==================== getItclVariableStateString ============================== */
    getItclVariableStateString: function(val) {
      var msg = "funny itcl variable state: ";
      return this.getGenericTypeString(this.itclVariableStates2String, msg, val);
    },

    /* ==================== getItclFunctionTypeString ============================== */
    getItclFunctionTypeString: function(val) {
      var msg = "funny itcl function type: ";
      return this.getGenericTypeString(this.itclFunctionTypes2String, msg, val);
    },

    /* ==================== getItclFunctionStateString ============================== */
    getItclFunctionStateString: function(val) {
      var msg = "funny itcl function state: ";
      return this.getGenericTypeString(this.itclFunctionStates2String, msg, val);
    },

    /* ==================== getItclOtherTypeString ============================== */
    getItclOtherTypeString: function(val) {
      var msg = "funny itcl other type: ";
      return this.getGenericTypeString(this.itclOtherTypes2String, msg, val);
    },

    /* ==================== getItclClassTypeString ============================== */
    getItclClassTypeString: function(val) {
      var msg = "funny itcl class type: "+val+"!";
      return this.getGenericTypeString(this.itclClassTypes2String, msg, val);
    },

    /* ==================== getItclFunctionStateString ============================== */
    getItclFunctionStateString: function(val) {
      var msg = "funny itcl function state: ";
      return this.getGenericTypeString(this.itclFunctionStates2String, msg, val);
    },

    /* ==================== getItclVariableStateString ============================== */
    getItclVariableStateString: function(val) {
      var msg = "funny itcl variable state: ";
      return this.getGenericTypeString(this.itclVariableStates2String, msg, val);
    },

    /* ==================== getNamespaceFlagString ============================== */
    getNamespaceFlagString: function(val) {
      var msg = "funny namespace flag: ";
      return this.getGenericTypeString(this.namespaceFlags2String, msg, val);
    },

    /* ==================== getResolverTypeString ============================== */
    getResolverTypeString: function(val) {
      var msg = "funny resolver type: ";
      return this.getGenericTypeString(this.resolverType2String, msg, val);
    },




    /* ==================== getVariableTypeFromString ============================== */
    getVariableTypeFromString: function(val) {
      var msg = "funny variable type: ";
      return this.getGenericTypeString(this.variableTypeStrings2VariableType, msg, val);
    },

    /* ==================== getVariableStateString ============================== */
    getVariableStateString: function(val) {
      var msg = "funny variable state: ";
      return this.getGenericTypeString(this.variableStateStrings2VariableState, msg, val);
    },

    /* ==================== getTraceTypeFromString ============================== */
    getTraceTypeFromString: function(val) {
      var msg = "funny trace type: ";
      return this.getGenericTypeString(this.traceTypeStrings2TraceType, msg, val);
    },

    /* ==================== getTraceOpFromString ============================== */
    getTraceOpFromString: function(val) {
      var msg = "funny trace op: ";
      return this.getGenericTypeString(this.traceOpStrings2TraceOp, msg, val);
    },

    /* ==================== getObjectTypeFromString ============================== */
    getObjectTypeFromString: function(val) {
      var msg = "funny object type string: ";
      return this.getGenericTypeString(this.objectTypeStrings2ObjectType, msg, val);
    },

    /* ==================== getProtectionFromString ============================== */
    getProtectionFromString: function(val) {
      var msg = "funny protection string: ";
      return this.getGenericTypeString(this.protectionStrings2Protection, msg, val);
    },

    /* ==================== getProtectionValFromString ============================== */
    getProtectionValFromString: function(val) {
      return this.getGenericTypeVal(this.protectionStrings2Protection, val);
    },

    /* ==================== getItclVariableTypeFromString ============================== */
    getItclVariableTypeFromString: function(val) {
      var msg = "funny itcl variable type string: ";
      return this.getGenericTypeString(this.itclVariableTypeStrings2ItclVariableType, msg, val);
    },

    /* ==================== getItclVariableStateFromString ============================== */
    getItclVariableStateFromString: function(val) {
      var msg = "funny itcl variable state string: ";
      return this.getGenericTypeString(this.itclVariableStateStrings2ItclVariableState, msg, val);
    },

    /* ==================== getItclFunctionTypeFromString ============================== */
    getItclFunctionTypeFromString: function(val) {
      var msg = "funny itcl function type string: ";
      return this.getGenericTypeString(this.itclFunctionTypeStrings2ItclFunctionType, msg, val);
    },

    /* ==================== getItclFunctionStateFromString ============================== */
    getItclFunctionStateFromString: function(val) {
      var msg = "funny itcl function state string: ";
      return this.getGenericTypeString(this.itclFunctionStateStrings2ItclFunctionState, msg, val);
    },

    /* ==================== getItclOtherTypeFromString ============================== */
    getItclOtherTypeFromString: function(val) {
      var msg = "funny itcl other type string: ";
      return this.getGenericTypeString(this.itclOtherTypeStrings2ItclOtherType, msg, val);
    },

    /* ==================== getItclClassTypeFromString ============================== */
    getItclClassTypeFromString: function(val) {
      var msg = "funny itcl class type string: ";
      return this.getGenericTypeString(this.itclClassTypeStrings2ItclClassType, msg, val);
    },

    /* ==================== getItclFunctionStateFromString ============================== */
    getItclFunctionStateFromString: function(val) {
      var msg = "funny itcl function state string: ";
      return this.getGenericTypeString(this.itclFunctionStateStrings2ItclFunctionState, msg, val);
    },

    /* ==================== getItclVariableStateFromString ============================== */
    getItclVariableStateFromString: function(val) {
      var msg = "funny itcl variable state string: ";
      return this.getGenericTypeString(this.itclVariableStateStrings2ItclVariableState, msg, val);
    },

    /* ==================== getNamespaceFlagFromString ============================== */
    getNamespaceFlagFromString: function(val) {
      var msg = "funny namespace flag string: ";
      return this.getGenericTypeString(this.namespaceFlagsStrings2namespaceFlag, msg, val);
    },

    /* ==================== getResolverTypeFromString ============================== */
    getResolverTypeFromString: function(val) {
      var msg = "funny resolver type string: ";
      return this.getGenericTypeString(this.resolverTypeStrings2ResolverType, msg, val);
    },

    /* ==================== getItclTypeFromString ============================== */
    getItclTypeFromString: function(val) {
      var base = this;
      var result;

      result =  base.getGenericTypeVal(base.itclVariableTypeStrings2ItclVariableType, val);
      if (result != null) {
        return result;
      }
      result =  base.getGenericTypeVal(base.itclFunctionTypeStrings2ItclFunctionType, val);
      if (result != null) {
        return result;
      }
      result =  base.getGenericTypeVal(base.itclOtherTypeStrings2ItclOtherType, val);
      return result;
    },

    /* ==================== escape_key ============================== */
    escape_key: function(key) {
      if (key == null) {
        return key;
      }
      switch (key.toString()) {
      case "constructor":
      case "destructor":
      case "join":
      case "function":
        key = "_"+key;
        break;
      }
      return key;
    },

    /* ==================== unescape_key ============================== */
    unescape_key: function(key) {
      if (key == null) {
        return key;
      }
      switch (key.toString()) {
      case "_constructor":
      case "_destructor":
      case "_join":
      case "_function":
        key = key.substring(1);
        break;
      }
      return key;
    },

    /* ==================== ensembleCommand ===================================== */
    /** Manage subcommands */
    ensembleCommand: function (interp, argv, cmd) {
      var sub;
      var main;
      var result;
      var ens;

      ens = cmd.ensemble;
      while (argv.length > 1) {
        sub  = argv[1].toString();
        main = argv.shift().toString()+" "+sub;
        argv[0] = main;
        if (ens == null || ens[sub] == null) {
          throw "Not an ensemble command 2: "+main;
        }
        result = ens[sub];
        if (result.ensemble == null) {
          if (typeof result.u.native_fcn.cmd_proc != "undefined") {
	    /* found the final command, stop in front of possible arguments */ 
            break;
          }
        }
        ens = result.ensemble;
      }
//print("ensembleCommand 1!"+ens+"!"+result.name+"!"+argv+"!"+argv.length+"!");
      var res = result.call(interp, argv);
//print("ensembleCommand res!"+result.name+"!"+res+"!");
//print("RES!"+typeof res+"!"+(res instanceof TclObject)+"!"+res.value_type+"!"+res.object_oid+"!"+typeof res.value+"!");
      return res
    },

    /* ==================== infoSubcommands ===================================== */
    /** Get subcommands of the current ensemble command. */
    infoSubcommands: function(interp, args) {
      var obj = this;
      var r = new Array();
      var lst = interp.list_obj_type.newListObj(null, 0);
      for (var i in obj.ensemble) {
        r.spuh(i);
      }
      interp.list_obj_type.listInsertElements(lst, 0, r.lgth, r);
      interp.setResult(lst);
      return interp.OK
    },

    /* ==================== panic ============================== */
    panic: function(cond, msg) {
      if (cond) {
        throw msg;
      }
    },

    /* ==================== relToAbsIndex ============================== */
    /* Convert a range, as returned by getRange(), into
     * an absolute index into an object of the specified length.
     * This function may return negative values, or values
     * bigger or equal to the length of the list if the index
     * is out of range. 
     */
    relToAbsIndex: function(len, idx) {
      var base = this;

      if (idx < 0) {
        return len + idx;
      }
      return idx;
    },

    /* ==================== relToAbsRange ============================== */
    /* Convert a pair of index as normalize by relToAbsIndex(),
     * into a range stored in first_ptr, last_ptr, range_len_ptr, suitable
     * for implementation of commands like [string range] and [lrange].
     *
     * The resulting range is guaranteed to address valid elements of
     * the structure. 
     */
    relToAbsRange: function(len, first, last, first_ptr, last_ptr, range_len_ptr) {
      var base = this;
      var range_len;

      if (first > last) {
        range_len = 0;
      } else {
        range_len = last - first + 1;
        if (range_len) {
          if (first < 0) {
            range_len += first;
            first = 0;
          }
          if (last >= len) {
            range_len -= (last - (len - 1));
            last = len - 1;
          }
        }
      }
      if (range_len < 0) {
        range_len = 0;
      }
      first_ptr[0] = first;
      last_ptr[0] = last;
      range_len_ptr[0] = range_len;
    },

    /* ==================== getOptions ============================== */
    getOptions: function(allowed_options, error_msg, args, num_option_fields_ptr, num_options_ptr) {
      var base = this;
      var r = new Object();
      var option;

      num_option_fields = 0;
      num_options = 0;
      for (var i = 0; i < args.length; i++) {
        option = args[i];
        if (option.toString().charAt(0) != "-") {
          /* seems to be end of options */
          break;
        }
        if (typeof allowed_options[option] == "undefined") {
          var msg = error_msg+" bad option: '"+option+"' should be one of: '";
          var sep = "";
          for (var opt in allowed_options) {
	     msg += sep + opt;
	     sep = ", "
          }
          throw msg;
        }
        var has_value = allowed_options[option];
        num_option_fields++;
        num_options++;
        if (has_value > 0) {
          i++;
          if (i == args.length) {
            throw error_msg+" must be an even number of option name and option value";
          }
          num_option_fields++;
          r[option] = args[i];
        } else {
          if (has_value == 0) {
            r[option] = "";
          } else {
            if (i+1 < args.length) {
	      var next_option = args[i+1].toString();
	      if (next_option.charAt(0) != "-") {
                i++;
                r[option] = args[i].toString();
	      } else {
                r[option] = "";
	      }
	    } else {
              r[option] = "";
	    }
          }
        }
      }
      num_option_fields_ptr[0] = num_option_fields;
      num_options_ptr[0] = num_options;
      return r;
    },

    /* ==================== getCallOptions ============================== */
    getCallOptions: function(allowed_options, args, msg_start, option_flags_ptr, options_ptr, error_msg_ptr, processed_args_ptr) {
      var base = this;
      var option;

      option_flags_ptr[0] = 0;
      options_ptr[0] = new Object();
      error_msg_ptr[0] = "";
      processed_args_ptr[0] = 0;
      for (var i = 0; i < args.length; i++) {
        option = args[i];
        if (option.toString().charAt(0) != "-") {
          /* seems to be end of options */
          break;
        }
        if (typeof allowed_options[option] == "undefined") {
          var msg = msg_start+" bad option: '"+option+"' should be one of: '";
          var sep = "";
          for (var opt in allowed_options) {
	     msg += sep + opt;
	     sep = ", "
          }
          error_msg_ptr[0] = msg;
	  return base.ERROR;
        }
	processed_args_ptr[0]++;
	option_flags_ptr[0] |= allowed_options[option].opt_code;
        var has_value = allowed_options[option].opt_val;
        if (has_value > 0) {
          i++;
          if (i == args.length) {
            error_msg_ptr[0] = msg_start+" must be an even number of option name and option value";
	    return base.ERROR;
          }
	  processed_args_ptr[0]++;
          options_ptr[0][option] = args[i];
        } else {
          if (has_value < 0) {
            if (i + 1 < args.length) {
	      var next_option = args[i + 1].toString();
	      if (next_option.charAt(0) != "-") {
                i++;
	        processed_args_ptr[0]++;
                options_ptr[0][option] = args[i].toString();
	      }
	    }
          }
        }
      }
      return base.OK;
    },

    /* ==================== foreachMapHelper ============================== */
    foreachMapHelper: function(interp, args, do_map) {
      var result = interp.ERROR;
      var i;
      var nbr_of_lists;
      var lists_idx;
      var lists_end;
      var nbr_of_loops = 0;
      var empty_str;
      var script;
      var map_res = null;
      var err = false;
      var out = false;

      if (args.length < 4 || args.length % 2 != 0) {
        interp.wrongNumArgs(1, args, "varList list ?varList list ...? script");
        return interp.ERROR;
      }
      if (do_map) {
        map_res = interp.list_obj_type.newListObj(null, 0);
        map_res.incrRefCount();
      }
      empty_str = interp.string_obj_type.newEmptyStringObj();
      empty_str.incrRefCount();
      script = args[args.length - 1];    /* Last argument is a script */
      nbr_of_lists = (args.length - 1 - 1) / 2;    /* args.length - 'foreach' - script */
      lists_idx = new Array();
      lists_end = new Array();
      /* Initialize iterators and remember max nbr elements each list */
      for (i = 0; i < nbr_of_lists * 2; i++) {
        lists_idx[i] = 0;
      }
      /* Remember lengths of all lists and calculate how much rounds to loop */
      for (i = 0; i < nbr_of_lists * 2; i += 2) {
        var cnt;
        var rem;
        var count;
  
        lists_end[i] = interp.list_obj_type.listLength(args[i + 1]);
        lists_end[i + 1] = interp.list_obj_type.listLength(args[i + 2]);
        if (lists_end[i] == 0) {
          interp.setResultString("foreach varlist is empty", -1);
          err = true;
	  break;
        }
        cnt = lists_end[i + 1] / lists_end[i];
        rem = lists_end[i + 1] % lists_end[i];
        count = cnt + (rem ? 1 : 0);
        if (count > nbr_of_loops) {
          nbr_of_loops = count;
        }
      }
      if (!err) {
        for (; nbr_of_loops-- > 0;) {
          for (i = 0; i < nbr_of_lists; ++i) {
            var var_idx = 0;
	    var vr = i * 2;
  
            while (var_idx < lists_end[vr]) {
              var var_name = new Array();;
	      var elem = new Array();
              var lst = i * 2 + 1;
  
              /* List index operations below can't fail */
              interp.list_obj_type.listIndex(args[vr + 1], var_idx, var_name, interp.FUNCTION_FLAGS_NONE);
	      var_name = var_name[0];
              if (lists_idx[i] < lists_end[lst]) {
                interp.list_obj_type.listIndex(args[lst + 1], lists_idx[i], elem, interp.FUNCTION_FLAGS_NONE);
	        elem = elem[0];
                /* Avoid shimmering */
                elem.incrRefCount();
                result = interp.variable_obj_type.setVariable(var_name, elem);
                elem.decrRefCount();
                if (result == interp.OK) {
                  ++lists_idx[i];  /* Remember next iterator of current list */
                  ++var_idx;       /* Next variable */
                  continue;
                }
              } else {
                if (interp.variable_obj_type.setVariable(var_name, empty_str) == interp.OK) {
                  ++var_idx;   /* Next variable */
                  continue;
                }
                err = true;
              }
            }
          }
	  if (!err) {
            result = interp.eval_statement.evalObj(script);
            switch (result) {
            case interp.OK:
              if (do_map)
                interp.list_obj_type.listAppendElement(map_res, interp.result);
              break;
            case interp.CONTINUE:
              break;
            case interp.BREAK:
              out = true;
              break;
            default:
              err = true;
              break;
            }
          }
	  if (out || err) {
            break;
	  }
        }
      }
      if (!err) {
        result = interp.OK;
        if (do_map) {
          interp.setResult(map_res);
        } else {
          interp.setEmptyResult();
        }
      }
      if (do_map) {
        map_res.decrRefCount();
      }
      empty_str.decrRefCount();
//      list_idx.free();
//      lists_end.free();
      return result;
    },

    /* ==================== source ===================================== */
    source: function (interp, url) {
//print("source!"+url+"!");
      interp.curr_file_name = url;
      url = interp.start_dir+"/"+url;
//print("source!"+url+"!"+typeof interp.win+"!");
      var xhr_object = null;
      if (interp.win != null) {
//      try {
//        if(typeof interp.win.ActiveXObject != "undefined") {    // Internet Explorer
//          xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
//        }
//      } catch(e) {
//      }
        if (xhr_object == null) {
          if(typeof interp.win.XMLHttpRequest != "undefined") { // Firefox
            xhr_object = new XMLHttpRequest();
          } else { // XMLHttpRequest not supported by the browser
            if (typeof readFile == "function") {
	      var responseText = readFile(url);
              return interp.eval_statement.evalObj(interp.string_obj_type.newStringObj(responseText), -1);
            } else {
              print("Your browser does not support XMLHTTP requests. " +
                    "Sorry that we cannot deliver this page.");
              return;
            }
          }
        }
      } else {
	var read_fcn = null;
        if (typeof readFile == "function") {
          read_fcn = readFile;
	}
        if (typeof read == "function") {
          read_fcn = read;
	}
        if (read_fcn != null) {
//print("source rhino2!"+url+"!"+interp.current_namespace.full_name+"!");
          var result = "";
          var responseText = read_fcn(url);
//print("responseText!"+responseText+"!");
          var script = interp.string_obj_type.newStringObj("::set dir "+interp.current_dir+"\n"+responseText, -1);
//print("SOURCE!"+script.len+"!"+url+"!"+script.toDebugString()+"!");
          try {
            result = interp.eval_statement.evalObj(script);
          } catch(e) {
print("SOURCE1!e!"+e+"!"+script.getString()+"!");
          }
//print("SOURCE END1!"+result+"!");
          return result;
        }
      }
      xhr_object.open("GET", url, false);
      xhr_object.send();
      var responseText = "::set dir "+interp.current_dir+"\n"+xhr_object.responseText.toString();
      var result = interp.eval_statement.evalObj(interp.string_obj_type.newStringobj(responseText), -1);
//print("SOURCE END2!"+result+"!");
      return result;
    },

    /* ==================== showProps ============================== */
    showProps: function(val) {
      print("props!");
      for (var z in val) {
        print("Z!"+z+"!"+val[z]+"!");
      }
      print("props END!");
    },

    /* ==================== mySelf ===================================== */
    mySelf: function () {
      return this.my_name+"!"+this.oid;
    },

  };

  Base.prototype.constructor = Base;
  R.Base = Base;

}, "0.0.1", {});
