function _aspxInsp(obj) {
	alert(_aspxGetObjInfo(obj));
}

function _aspxGetObjInfo(obj) {
	var array = new Array();
	for(var key in obj) {
	    if(key.indexOf("on") != 0 && key.indexOf("outer") != 0 && key.indexOf("inner") != 0) {
	        try{
			    var value = "" + eval("obj." + key);
			    if(value.indexOf("function") < 0)
				    array.push(" " + key + " = " + value);
		    }
		    catch(e){
		    }
		}
	}
	array.sort();
	return array.join("\t");
}

var ASPxJSProfilerCallInfo = function(procName, args) {
    this.procName = procName;
    this.argumentsList = (typeof(args) != "undefined" && args != null && args.length > 0) ? args : [ ];
    this.callDate = new Date();
    this.exitDate = null;
    
    this.Exit = function() {
        this.exitDate = new Date();
    }
    this.GetEnterInfo = function() {
        return this.GetInfo(">>");
    }
    this.GetExitInfo = function() {
        if (this.exitDate == null)
            throw 'JSProfilerCallInfo Exit() method was not called.';
        return this.GetInfo("<<", true);
    }
    this.GetInfo = function(prefix, writeExecutionTime) {
        var info = "";
        info += prefix;
        info += "&nbsp;";
        info += "<span style=\"color: blue;\">";
        info += this.procName;
        info += "(";
        info += "<span style=\"color: #F757FA;\">";
        for(var i = 0; i < this.argumentsList.length; i++) {
            info += this.argumentsList[i];
            if (i < this.argumentsList.length - 1)
                info += ", ";
        }
        info += "</span>";
        info += ")";
        info += "</span>";
        if (writeExecutionTime)
            info += "&nbsp; (execution time: <span style=\"color: blue\">" + this.GetExecutionSeconds(this.callDate, this.exitDate) + " sec</span>)";
        return info;
    }
    this.GetExecutionSeconds = function(callDate, exitDate) {
        return (exitDate.getTime() - callDate.getTime()) / 1000.0;
    }
}

var ASPxJSProfiler = {
    callStack: [ ],
    
    // API
    Enter: function(procName, args) {
        var callInfo = new ASPxJSProfilerCallInfo(procName, args);
        ASPxJSProfiler.WriteMessage(callInfo.GetEnterInfo());
        ASPxJSProfiler.callStack.push(callInfo);
    },
    Exit: function() {
        if (ASPxJSProfiler.callStack.length == 0)
            throw "CallStack is empty.";
        var callInfo = ASPxJSProfiler.callStack[ASPxJSProfiler.callStack.length - 1];
        callInfo.Exit();
        ASPxJSProfiler.callStack.pop();
        ASPxJSProfiler.WriteMessage(callInfo.GetExitInfo());
    },
    
    // Utils
    CreateIndentString: function() {
        var indent = "";
        for (var i = 0; i < ASPxJSProfiler.callStack.length; i++)
            indent += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        return indent;
    },
    WriteError: function(message) {
        ASPxJSProfiler.WriteMessageCore(message, "red");
    },
    WriteWarning: function(message) {
        ASPxJSProfiler.WriteMessageCore(message, "#E8DD44");
    },
    Write: function(message) {
        ASPxJSProfiler.WriteMessage(message);
    },
    WriteMessage: function(message) {
        ASPxJSProfiler.WriteMessageCore(message, "green");
    },
    WriteMessageCore: function(message, colorStr) {
        var para = document.createElement("P");
        para.style.fontSize = "12px";
        para.style.margin = "1px 0";
        para.style.color = colorStr;
        para.style.whiteSpace = "nowrap";
        para.style.fontFamily = "Consolas, Arial, Tahoma";
        para.innerHTML = ASPxJSProfiler.CreateIndentString() + message;
        document.body.appendChild(para);
    }
};