//============================================================================
// Jocys.com JavaScript.NET Classes               (In C# Object Oriented Style)
// Created by Evaldas Jocys <evaldas@jocys.com>
//=============================================================================
// Namespaces
//-----------------------------------------------------------------------------
// <PropertyGroup>
//		<RootNamespace>System</RootNamespace>
// <PropertyGroup>
//-----------------------------------------------------------------------------

var System = {};

self.System = {
	__namespace: true,
	__typeName: "Sys",
	getName: function () { return "Sys"; },
	__upperCaseTypes: {}
};

//-----------------------------------------------------------------------------
// CLASS: System.Type
//-----------------------------------------------------------------------------

System.Type = function () {
	/// <summary>
	/// Initializes a new instance of the System.Type class.
	/// </summary>
	/// <remarks>These XML Comments were created only for IntelliSense.</remarks>
	/// <summary>
	/// Initializes a new instance of the System.Type class.
	/// </summary>
	this.Name = "name";
	this.Namespace = "";
	this.FullName = "";
	//---------------------------------------------------------
	this.ToString = function () {
		/// <summary>
		/// Returns a String representing the name of the current Type.
		/// </summary>
		/// <returns>A String representing the name of the current System.Type.</returns>
		return this.FullName;
	};
	//---------------------------------------------------------
	function initialize() {
		var tn = "";
		tn = arguments[0];
		this.FullName = tn;
		var ta = [];
		if (tn) {
			ta = tn.split('.');
			this.Name = ta[ta.length - 1];
			this.Namespace = ta.slice(0, ta.length - 2).join('.');
			//tnarguments[0];
			//tn.
			//this.Namespace = nspace;
			//this.Name = name;
			//this.FullName = this.Namespace +"."+ this.Name
		}
	}
	initialize.apply(this, arguments);
};

//-----------------------------------------------------------------------------

System.Type.Inherits = function (d, s) {
	for (var property in s) {
		if (property === "__typeName") continue;
		if (property === "GetType") continue;
		d[property] = s[property];
	}
	return s;
};

//-----------------------------------------------------------------------------

System.Type.RegisterNamespace = function (namespacePath) {
	// If Microsoft Ajax function exist then...
	if (typeof Type !== "undefined" && typeof Type.registerNamespace === "function") {
		// Register namespace.
		//Type.registerNamespace.
		Type.registerNamespace.apply(this, arguments);
	} else {
		var rootObject = self;
		var namespaceParts = namespacePath.split('.');
		for (var i = 0; i < namespaceParts.length; i++) {
			var currentPart = namespaceParts[i];
			var ns = rootObject[currentPart];
			if (!ns) ns = rootObject[currentPart] = {};
			ns.__typeName = namespacePath;
			ns.__namespace = true;
			rootObject = ns;
		}
	}
};

//-----------------------------------------------------------------------------

System.Type.RegisterClass = function (typeName, type, baseType, interfaceTypes) {
	var o = type;
	// If Microsoft Ajax function exist then...
	if (typeof Type !== "undefined" && typeof Type.registerClass === "function") {
		// Register class.
		Type.registerClass.apply(o, arguments);
	} else {
		o.__typeName = typeName;
		o.__class = true;
	}
	o.prototype.GetType = function () { return new System.Type(typeName); };
};

//-----------------------------------------------------------------------------

System.Type.RegisterInterface = function (typeName, baseType) { };

//-----------------------------------------------------------------------------

System.Type.RegisterEnum = function (type, flags) {
	// If Microsoft Ajax function exist then...
	var o = eval(type);
	if (typeof Type !== "undefined" && typeof Type.registerEnum === "function") {
		// Register namespace.
		Type.registerEnum.apply(o, arguments);
	} else {
		for (var i in o.prototype) o[i] = o.prototype[i];
		o.__enum = true;
		o.__flags = flags;
	}
};

//-----------------------------------------------------------------------------

System.Type.RegisterProperty = function (name) {
	var o = me[name];
	me[name] = function (value) {
		if (arguments.length === 0) return me[name].get();
		if (arguments.length === 1) me[name].set(value);
	};
};

//-----------------------------------------------------------------------------

System.Type.RegisterNamespace("System");
System.Type.RegisterClass("System.Type", System.Type);

//-----------------------------------------------------------------------------


System.Type.GetType = function (typeName) {
	/// <summary>
	/// Gets the System.Type with the specified name, performing a case-sensitive
	/// search.
	/// </summary>
	/// <param type="string" name="typeName">The name of the System.Type.AssemblyQualifiedName to get.</param>
	/// <returns type="System.Type">
	/// The System.Type with the specified name, if found; otherwise, null.
	/// </returns>
	var type = new System.Type(typeName);
	return type;
};

//=============================================================================

//=============================================================================
// TypeCode Enum
//-----------------------------------------------------------------------------

System.TypeCode = function () {
	/// <summary>Specifies the type of an object.</summary>
	/// <field name="Empty" type="Number" integer="true" static="true">A null reference.</field>
	/// <field name="Object" type="Number" integer="true" static="true">Represents any reference or value type not represented by another TypeCode.</field>
	/// <field name="DBNull" type="Number" integer="true" static="true">A database null (column) value.</field>
	/// <field name="Boolean" type="Number" integer="true" static="true">A simple type representing Boolean values of true or false.</field>
	/// <field name="Char" type="Number" integer="true" static="true">Unsigned 16-bit integers with values between 0 and 65535.</field>
	/// <field name="SByte" type="Number" integer="true" static="true">Signed 8-bit integers with values between -128 and 127.</field>
	/// <field name="Byte" type="Number" integer="true" static="true">Unsigned 8-bit integers with values between 0 and 255.</field>
	/// <field name="Int16" type="Number" integer="true" static="true">Signed 16-bit integers with values between -32768 and 32767.</field>
	/// <field name="UInt16" type="Number" integer="true" static="true">Unsigned 16-bit integers with values between 0 and 65535.</field>
	/// <field name="Int32" type="Number" integer="true" static="true">Signed 32-bit integers with values between -2147483648 and 2147483647.</field>
	/// <field name="UInt32" type="Number" integer="true" static="true">Unsigned 32-bit integers with values between 0 and 4294967295.</field>
	/// <field name="Int64" type="Number" integer="true" static="true">Signed 64-bit integers with values between -9223372036854775808 and 9223372036854775807.</field>
	/// <field name="UInt64" type="Number" integer="true" static="true">Unsigned 64-bit integers with values between 0 and 18446744073709551615.</field>
	/// <field name="Single" type="Number" integer="true" static="true">A floating point type representing values ranging from approximately 1.5 x 10 -45 to 3.4 x 10 38 with a precision of 7 digits.</field>
	/// <field name="Double" type="Number" integer="true" static="true">A floating point type representing values ranging from approximately 5.0 x 10 -324 to 1.7 x 10 308 with a precision of 15-16 digits.</field>
	/// <field name="Decimal" type="Number" integer="true" static="true">A simple type representing values ranging from 1.0 x 10 -28 to approximately 7.9 x 10 28 with 28-29 significant digits.</field>
	/// <field name="DateTime" type="Number" integer="true" static="true">A type representing a date and time value.</field>
	/// <field name="String" type="Number" integer="true" static="true">A sealed class type representing Unicode character strings.</field>
};

System.TypeCode.prototype = {
	Empty: 0,
	Object: 1,
	DBNull: 2,
	Boolean: 3,
	Char: 4,
	SByte: 5,
	Byte: 6,
	Int16: 7,
	UInt16: 8,
	Int32: 9,
	UInt32: 10,
	Int64: 11,
	UInt64: 12,
	Single: 13,
	Double: 14,
	Decimal: 15,
	DateTime: 16,
	String: 18
};

System.Type.RegisterEnum(System.TypeCode);

//=============================================================================
// TimeUnitType Enum
//-----------------------------------------------------------------------------

System.TimeUnitType = function () { };

System.TimeUnitType.prototype = {
	Seconds: 0,
	Minutes: 1,
	Hours: 2,
	Days: 3
};

System.Type.RegisterEnum(System.TimeUnitType);

//=============================================================================
// Extensions
//-----------------------------------------------------------------------------

System.SR = function () { };
System.SR.prototype = {
	// System.resources
	NotReadableStream: "The base stream is not readable.",
	NotWriteableStream: "The base stream is not writeable.",
	ArgumentOutOfRange_Enum: "Enum value was out of legal range."
};
System.Type.RegisterClass("System.SR", System.SR);

System.SR.GetString = function (name) {
	/// <summary>
	/// Searches for a <see cref="T:System.String" /> resource with the specified name.
	/// </summary>
	/// <param name="name">Name of the resource to search for.</param>
	/// <returns>The value of a resource, if the value is a <see cref="T:System.String" />.</returns>
	var message = System.SR.prototype[name];
	if (!message) message = name;
	return message;
};

//=============================================================================
// Extensions
//-----------------------------------------------------------------------------
System.Extensions = function () {
	/// <summary>
	/// Create class to extend javascript objects. This function will run at the end
	/// of this file.
	/// </summary>
	//---------------------------------------------------------
	// METHOD: Apply
	//---------------------------------------------------------
	this.Apply = function () {
		var isServerSide = false;
		if (typeof Response === "object") isServerSide = true;
		if (!isServerSide) {
			// Create function $(...) - Get objects by Ids.
			if (typeof this.$ === "undefined") this.$ = function () {
				return document.getElementById(arguments[0]);
			};
		}

		// EXTENSIONS: Object
		//Object.prototype.ToTrace = function(){ System.Class.ListProperties(this,this.toString());};
		//		Object.prototype.GetType = function(){
		//			//if (typeof(this.GetType) == "function") return this.GetType();
		//			var type = new System.Type();
		//			type.Name = typeof(this);
		//			return type;
		//		}


		// EXTENSIONS: Date
		Date.prototype.SubtractDays = System.DateTime.SubtractDays;
		Date.prototype.SubtractMonths = System.DateTime.SubtractMonths;
		Date.prototype.GetFromString = System.DateTime.GetFromString;
		Date.prototype.GetFromUtcString = System.DateTime.GetFromUtcString;
		Date.prototype.DefaultFormat = "yyyy-MM-dd HH:mm:ss";
		Date.prototype.ToString = System.DateTime.ToString;
		Date.prototype.Subtract = System.DateTime.Subtract;
		Date.prototype.Ticks = System.DateTime.Ticks;
		Date.prototype.ToUniversalTime = System.DateTime.ToUniversalTime;
		Number.prototype.ToString = Number.prototype.toString;

		// EXTENSIONS: String
		String.prototype.Trim = function (string) { return System.Text.Trim(this, string); };
		String.prototype.ToCamelCase = function () { return System.Text.ToCamelCase(this); };
		String.Format = function (format, args) {
			/// <summary>Appends the string returned by processing a composite format string.</summary>
			/// <param name="format">A composite format string.</param>
			/// <param name="An array of objects to format.">A composite format string.</param>
			/// <returns>A reference to this instance with format appended.</returns>
			//
			// Sync this method with String.Format later.
			args = Array.prototype.slice.call(arguments, 1);
			var value = format.replace(/{(\d+)(:([xX]?\d+))?(,([-]?\d+))?}/g,
				function (matchString, number) {
					var value = typeof args[number] !== 'undefined' ? args[number] : matchString;
					var hexMatch = matchString.match(":([xX])(\\d+)");
					if (hexMatch) {
						value = value.toString(16);
						// Change case.
						value = hexMatch[1] === "x"
							? value.toLowerCase()
							: value.toUpperCase();
						// Add zeros.
						num = parseInt(hexMatch[2]);
						var z = "";
						for (i = value.length; i < num; i++)
							z += "0";
						value = z + value;
					}
					var padMatch = matchString.match(",([-]?\\d+)");
					var num;
					if (padMatch) {
						num = parseInt(padMatch[1]);
						value = value.toString();
						var ln = Math.abs(num);
						var s = "";
						for (i = value.length; i < ln; i++)
							s += " ";
						value = num >= 0
							? s + value
							: value + s;
					}
					return value;
				});
			return value;
		};
		String.Join = function (separator, value, startIndex, count) {
			if (!separator) separator = "";
			if (!startIndex) startIndex = 0;
			if (!count) count = value.length;
			if (count === 0) return "";
			var length = 0;
			var end = startIndex + count - 1;
			var s = "";
			for (var i = startIndex; i <= end; i++) {
				if (i > startIndex) s += separator;
				s += value[i];
			}
			return s;
		};
		// EXTENSIONS: Array
		Array.prototype.Clone = function () {
			var buffer = this.slice(0, this.length);
			for (var i = 0; i < this.length; i++) buffer[i] = this[i];
			return buffer;
		};
		//		// Firefox InnerText
		//		if (typeof HTMLElement != "undefined" && typeof HTMLElement.prototype.__defineGetter__ != "undefined"){
		//			HTMLElement.prototype.__defineGetter__("innerText", function(){ return this.textContent; });
		//			HTMLElement.prototype.__defineSetter__("innerText", function(sText){ this.innerHTML = sText.textContent; });
		//		}


	};
};
System.Type.RegisterClass("System.Extensions", System.Extensions);


//=============================================================================
// CLASS: System.IO.Compression.DeflateStream
//-----------------------------------------------------------------------------

System.AsyncCallback = function (ar) {
	/// <summary>
	/// References a method to be called when a corresponding asynchronous operation completes.
	/// </summary>
	/// <param name="ar">The result of the asynchronous operation.</param>
};
System.Type.RegisterClass("System.AsyncCallback", System.AsyncCallback);

System.AsyncWriteDelegate = function (array, offset, count, isAsync) {
	// internal delegate void AsyncWriteDelegate(byte[] array, int offset, int count, bool isAsync);
};
System.Type.RegisterClass("System.AsyncWriteDelegate", System.AsyncWriteDelegate);

//=============================================================================
// Client side extensions
//-----------------------------------------------------------------------------

System.GetScriptsPath = function () {
	var url = "";
	var i;
	var match;
	var rx = new RegExp("System(\.debug)?\.js", "gi");
	var head = document.getElementsByTagName("head")[0];
	var scripts = head.getElementsByTagName("script");
	for (i = 0; i < scripts.length; i++) {
		match = scripts[i].src.match(rx);
		if (match) {
			url = scripts[i].src.replace(rx, "");
			break;
		}
	}
	// If url is still empty then...
	if (url.length === 0) {
		scripts = document.getElementsByTagName("script");
		for (i = 0; i < scripts.length; i++) {
			match = scripts[i].src.match(rx);
			if (match) {
				url = scripts[i].src.replace(rx, "");
				break;
			}
		}
	}
	return url;
};

// Make this class static.
System.Extensions = new System.Extensions();
// Use this to apply extensions to current context.
// System.Extensions.Apply.apply(this);

//=============================================================================
// System.Type.Class
//-----------------------------------------------------------------------------

/* Every JavaScript object has a prototype property. This property is what makes
OOP possible in JavaScript, but it is a bit unusual if you come from other
OO languages. Here's how it works. When you access an object property, the
interpreter will look at the current object's properties to see if one by that
name exists. If the name does not exist there, then the interpreter looks at the
prototype property of the object to see if that object, the one pointed to by
the prototype property, has the named property. If there is no property there,
then the interpreter looks to see if the prototype property has a prototype
property. If it does, then this process continues until either the property is
found or until there are no more prototype properties to search. */

System.Type.Class = System.Type.Class ? System.Type.Class : {};

System.Type.Class.Root = this;

System.Type.Class.Inherit = function () {
	/// <summary>
	/// 
	/// </summary>
	/// <returns>void</returns>
	Trace.Write("exec System.Class.Inherit(arguments){", 1);
	// Create object
	this.Classes = [];
	this.Objects = [];
	var i;
	for (i = 0; i < arguments.length; i++) {
		// We need to tell to class to skip initialization.
		arguments[i].prototype.NoInit = true;
		this.Objects.push(new arguments[i]);
		arguments[i].prototype.NoInit = false;
		this.Classes.push(arguments[i]);
	}
	for (i = 0; i < this.Objects.length; i++) {
		if (i === 0) {
			Trace.Write("Inherit: '" + this.Objects[i].Type + "' Class From: ", 1);
		} else {
			Trace.Write(this.Objects[i].Type);
		}
	}
	Trace.Write("Done", -2);

	var finClass = this.Classes[0];
	var finObject = this.Objects[0];

	for (var cid = this.Classes.length - 1; cid > 0; cid--) {
		var srcClass = this.Classes[cid];
		var srcObject = this.Objects[cid];
		var dstObject = this.Objects[cid - 1];
		var dstClass = this.Classes[cid - 1];

		Trace.Write("// Inherit: '" + dstObject.Type + "' From: '" + srcObject.Type + "'");
		//Trace.Write("Inherit: "+dstClass+" From: "+srcClass);

		//METHOD1: Copy properties one by one into destination class prototype object.
		finClass.prototype = srcObject;
		Trace.Write("1. Import Class Properties: " + finObject.Type + ".prototype <- " + srcObject.Type, 1);
		// Copy one by one method.
		//for (var property in srcObject){
		//	Trace.Write("."+property+"");
		//	finClass.prototype[property] = srcObject[property];
		//}
		Trace.Write("End Import", -2);
		// The constructor property is used in scripts to determine an object's
		// type. When we redefined the destinationClass prototype, we effectively
		// changed the constructor to sourceClass. We need to fix this and
		// Update subclass properties and methods.
		Trace.Write("2. Fix Prototype Constructor", 1);
		finClass.prototype.constructor = finClass;
		// Copy one by one method.
		//Trace.Write("Assign property: "+finObject.Type+" <- "+srcObject.Type+"["+property+"]");
		//for (var property in finObject){
		//	finClass.prototype.constructor[property] = finObject[property];
		//}
		Trace.Write("End Fix", -2);
		// Allow to call methods in a superclass that are hidden by redefined methods in a subclass.
		Trace.Write("3. Allow to call methods in a superclass", 1);
		//destinationClass.superclass = sourceClass.prototype;
		Trace.Write("Import Superclass Properties: " + finObject.Type + ".superclass <- " + srcObject.Type + ".prototype");
		finClass.superclass = srcClass.prototype;
		// Copy one by one method.
		//for (var property in srcClass.prototype){
		//	//Trace.Write("Assign property: "+finObject.Type+" <- "+srcObject.Type+"["+property+"]");
		//	finClass.superclass[property] = srcClass.prototype[property];
		//}
		Trace.Write("End Import", -2);
		//System.Class.ListProperties(finClass,"finClass");
	}
	Trace.Write("} //System.Class.Inherit(arrguments)", -2);
};

System.Type.Class.Inherit = function (classTo, classFrom) {
	/// <summary>
	/// Inherit one class (subclass) from another (superclass);
	/// </summary>
	/// <returns>void</returns>
	classTo.prototype = new classFrom();
	// Update subclass properties and methods.
	classTo.prototype.constructor = classTo;
	// Allow to call methods in a superclass that are hidden by redefined methods in a subclass.
	classTo.superclass = classFrom.prototype;
};


System.Type.Class.Exists = function (path) {
	/// <summary>
	/// Check if namespace exists.
	/// </summary>
	/// <returns>
	/// True if namespace exists, false if not.
	/// </returns>
	var rootObject;
	// If this is server side then...
	if (typeof Response === "object") {
		rootObject = System.Class.Root;
	} else {
		rootObject = System.Class.Root; //window;
	}
	var exists = true;
	var parts = path.split('.');
	for (var i = 0; i < parts.length; i++) {
		var part = parts[i];
		// If namespace does not exists then...
		//Trace.Write("Part: "+part);
		if (!rootObject[part]) {
			// return false.
			exists = false;
			break;
		}
		rootObject = rootObject[part];
	}
	return exists;
};

// Added for compatibility only. Will be removed later.
// Make sure that the sub namespace Client exists.
System.Class = System.Class ? System.Class : {};
System.Class.Inherit = System.Type.Class.Inherit;
System.Class.Root = this;

//=============================================================================
// CLASS: Uri
//-----------------------------------------------------------------------------

System.Uri = function (uriString) {
	/// <summary>
	/// Initializes a new instance of the System.Uri class with the specified URI.
	/// </summary>
	/// <param type="string" name="uriString">A URI</param>
	//---------------------------------------------------------
	// http://www.domain.com:80/default.aspx?AudioMin=0&AudioMax=100
	this.OriginalString;
	// http://www.domain.com:80/default.aspx
	this.AbsolutePath;
	// ?AudioMin=0&AudioMax=100
	this.Query;
	this.QueryParams;
	this.GetType = function () { return new System.Type("System.Uri"); };
	//---------------------------------------------------------
	this.GetQueryValue = function (name, ignoreCase) {
		var value = null;
		var pName;
		if (ignoreCase === true) name = name.toLowerCase();
		for (var property in this.QueryParams) {
			pName = property;
			if (ignoreCase === true) pName = property.toLowerCase();
			if (name === pName) {
				value = this.QueryParams[property];
				break;
			}
		}
		return value;
	};
	//---------------------------------------------------------
	this.GetParameters = function (uri) {
		var results = {};
		if (uri === null) return results;
		var query = uri.substring(uri.indexOf("?") + 1, uri.length);
		var arr = query.split("&");
		var item;
		var name;
		var value;
		for (var i = 0; i < arr.length; i++) {
			item = arr[i];
			name = item.substring(0, item.indexOf("="));
			value = item.substring(item.indexOf("=") + 1, item.length);
			value = unescape(value);
			results[name] = value;
		}
		return results;
	};
	//---------------------------------------------------------
	function initialize() {
		var u = arguments[0];
		this.OriginalString = u;
		this.AbsolutePath = u.indexOf("?") > -1 ? u.substring(0, u.indexOf("?") - 1) : u;
		this.Query = u.indexOf("?") > -1 ? u.substring(u.indexOf("?"), u.length) : null;
		this.QueryParams = this.GetParameters(this.Query);
	}
	initialize.apply(this, arguments);
};
System.Type.RegisterClass("System.Uri", System.Uri);

//=============================================================================
// CLASS: EventItem
//-----------------------------------------------------------------------------

//Using Delegates (C# Programming Guide)
// http://msdn2.microsoft.com/en-us/library/ms173172.aspx

System.EventItem = function () {
	this.Node;
	this.Name;
	this.Handler;
	this.Capture;
};
System.Type.RegisterClass("System.EventItem", System.EventItem);

//=============================================================================
// CLASS: EventHandler (Delegate)
//-----------------------------------------------------------------------------

System.EventHandler = function (target, method, timeout) {
	/// <summary>
	/// This helper class simulates .NET concept of event delegate. (EventHandler)
	/// </summary>
	/// <param type="function" name="method">Method represented by Delegate.<param>
	/// <param type="object" name="target">Context on which delegate invokes the instance method.<param>
	/// <param type="int" name="timout">Add delay (in miliseconds) between event notification from source object and call of recipient object that have registered to receive that event.</param>
	var me = this;
	//---------------------------------------------------------
	this.Method = null;
	this.Target = null;
	this.Timeout = null;
	//---------------------------------------------------------
	this.Invoke = function () {
		if (typeof this.Timeout === "number") {
			setTimeout(function () { return this.Method.apply(this.Target, arguments); }, this.Timeout);
		} else {
			return this.Method.apply(this.Target, arguments);
		}
	};
	//---------------------------------------------------------
	this.InvokeNative = function () {
		var e = arguments[0] || self.event;
		var sender = e.target || e.srcElement;
		var args = new Array(2);
		args[0] = sender;
		args[1] = e;
		if (typeof timeout === "number") {
			setTimeout(function () { return method.apply(target, args); }, timeout);
		} else {
			return method.apply(target, args);
		}
	};
	//---------------------------------------------------------
	this.Initialize = function () {
		this.Target = target;
		this.Method = method;
		//System.Class.Properties.ToTrace(me);
		//Trace.Write(typeof(me.Target)+": "+nativeEvent);
	};
	this.Initialize();
};
System.Type.RegisterClass("System.EventHandler", System.EventHandler);

//=============================================================================
// CLASS: Event
//-----------------------------------------------------------------------------

System.Event = function (name) {
	/// <summary>
	/// This class simulates .NET eventing. (event delegate)
	/// </summary>
	//---------------------------------------------------------
	this.args = {};
	this._delegates = [];
	this.name = name;
	//---------------------------------------------------------
	this.Add = function (delegate) {
		/// <summary>
		/// This function is used to add a callback object.
		/// and a method.
		/// </summary>
		this._delegates[this._delegates.length] = delegate;
	};
	//---------------------------------------------------------
	this.Remove = function (delegate) {
		/// <summary>
		/// This function is used to remove a callback object.
		/// and a method.
		/// </summary>
		for (i = this._delegates.length - 1; i >= 0; i = i - 1) {
			if (delegate === this._delegates[i]) {
				this._delegates.splice(i, 1);
			}
		}
	};
	//---------------------------------------------------------
	this.Fire = function (sender, eventArgs) {
		/// <summary>
		/// This function makes a call back into the object
		/// that has registered for the event.
		/// </summary>
		for (var i = 0; i < this._delegates.length; i++) {
			this._delegates[i].Invoke(sender, eventArgs);
		}
	};
};
System.Type.RegisterClass("System.Event", System.Event);

//=============================================================================
// CLASS: EventArgs
//-----------------------------------------------------------------------------

System.EventArgs = function (name) {
	/// <summary>
	/// Event arguments.
	/// </summary>
	/// <param name="name">Name of event</param>
	this.Name = "";
	//---------------------------------------------------------
	this.ToString = function () {
		/// <summary>
		/// Convert this object to string representation.
		/// </summary>
		var results = "";
		for (var property in this) {
			var skip = false;
			// Don't show own methods.
			skip = skip || property === "Initialize";
			skip = skip || property === "ToString";
			if (!skip) results += property + "='" + this[property] + "';";
		}
		results = "e[" + results + "]";
		return results;
	};
	//---------------------------------------------------------
	this.Initialize = function (name) {
		this.Name = name ? name : "";
	};
	this.Initialize.apply(this, arguments);
};
System.Type.RegisterClass("System.EventArgs", System.EventArgs);

//=============================================================================
// CLASS: EventsManager
//-----------------------------------------------------------------------------

System.EventsManager = function (context) {
	/// <summary>
	/// Provides a way for automagically removing events from nodes and thus preventing memory leakage.
	/// </summary>
	/// <param name="context">Optional context of events. Default: window</param>
	/// <example>
	/// // Attach SomeButton_Click function to "click" event of "SomeButton" button.
	/// Events.Add("SomeButton", "click", SomeButton_Click, false);
	/// // Attach ButtonWithDelay_Click function to event "click" of "ButtonWithDelay" button.
	/// // Delay execution by 2 seconds and run ButtonWithDelay_Click in this context.
	/// Events.Add("ButtonWithDelay", "click", ButtonWithDelay_Click, false, this, 2000);
	/// </example>
	/// <remarks>
	/// Original Idea by Mark Wubben
	/// Rewriten as class by Evaldas Jocys [evaldas@jocys.com]
	/// See http://novemberborn.net/javascript/event-cache for more information.
	/// </remarks>
	//---------------------------------------------------------
	// Public properties.
	//---------------------------------------------------------
	// An array whose items are arrays which contain the information in the
	// following order: node, eventName, eventHandler, capture.
	this.Items = null;
	this.Context = null;
	//---------------------------------------------------------
	// Private properties.
	//---------------------------------------------------------
	var me = this;
	//---------------------------------------------------------
	// METHOD: Add
	//---------------------------------------------------------
	this.Add = function (node, eventName, eventHandler, capture) {
		/// <param type="bool" name="capture">true or false if we need to atach something to native DOM object.</param>
		var success = true;
		var id;
		if (typeof node === "string") {
			node = this.Context.document.getElementById(node);
			id = node;
		} else {
			id = node.id;
		}
		var traceFound = typeof Trace !== "undefined";
		if (traceFound) {
			Trace.Write("call " + this.GetType().Name + ".Add(node, '" + eventName + "', eventHandler, " + capture + ")");
		}
		if (node) {
			if (typeof capture !== "boolean") {
				node[eventName].Add(eventHandler);
			} else {
				if (eventHandler.GetType && eventHandler.GetType().FullName === "System.EventHandler") eventHandler = eventHandler.InvokeNative;
				// Attach handler to native DOM object.
				if (node.addEventListener) {
					node.addEventListener(eventName, eventHandler, capture);
				} else if (node.attachEvent) {
					if (traceFound) Trace.Write("thru System.EventHandler: " + eventHandler.Type);
					var r = node.attachEvent("on" + eventName, eventHandler);
				} else { /* */ }
				this.AddItem(node, eventName, eventHandler, capture);
			}
		} else {
			if (traceFound) Trace.Write("Error: " + this.GetType().Name + ".Add(...) - node '" + id + "' was not found!");
			success = false;
		}
		return success;
	};
	//---------------------------------------------------------
	// METHOD: Remove
	//---------------------------------------------------------
	// Use value returned by by this.Add if you want to remove same function.
	this.Remove = function (node, eventName, eventHandler) {
		if (typeof node === "string") node = this.Context.document.getElementById(node);
		this.RemoveItem(node, eventName, eventHandler);
	};
	//---------------------------------------------------------
	// METHOD: AddItem
	//---------------------------------------------------------
	// node - A reference to the node on which the event has been set.
	// eventName - The name of the event.
	// eventHandler - A reference to the function which handles the event.
	// capture - determines whether the event is triggered in capture mode
	// or not. Does not apply to Internet Explorer.
	this.AddItem = function (node, eventName, eventHandler, capture) {
		var ev = new System.EventItem();
		ev.Node = node;
		ev.Name = eventName;
		ev.Handler = eventHandler;
		ev.Capture = capture;
		this.Items.push(ev);
	};
	//---------------------------------------------------------
	// METHOD: RemoveItem
	//---------------------------------------------------------
	this.RemoveItem = function (node, eventName, eventHandler) {
		var i, item;
		for (i = this.Items.length - 1; i >= 0; i = i - 1) {
			item = this.Items[i];
			if (typeof item.Capture !== "boolean") {
				item.Node[item.Name].Remove(item.Handler);
			} else {
				if (eventHandler.GetType && eventHandler.GetType().FullName === "System.EventHandler") eventHandler = eventHandler.InvokeNative;
				if (node === item.Node && eventName === item.Name && eventHandler === item.Handler) {
					if (item.Node.removeEventListener) {
						item.Node.removeEventListener(item.Name, item.Handler, item.Capture);
					} else if (item.Node.detachEvent) {
						item.Node.detachEvent("on" + item.Name, item.Handler);
					}
				}
			}
		}
	};
	//---------------------------------------------------------
	// METHOD: Dispose
	//---------------------------------------------------------
	// Remove all cached events.
	this.Dispose = function () {
		var i, item;
		for (i = me.Items.length - 1; i >= 0; i = i - 1) {
			item = me.Items[i];
			if (typeof item.Capture !== "boolean") {
				item.Node[item.Name].Remove(item.Handler);
			} else {
				var eventHandler = item.Handler;
				if (eventHandler.GetType && eventHandler.GetType().FullName === "System.EventHandler") eventHandler = eventHandler.InvokeNative;
				if (item.Node.removeEventListener) {
					item.Node.removeEventListener(item.Name, item.Handler, item.Capture);
				} else if (item.Node.detachEvent) {
					item.Node.detachEvent("on" + item.Name, item.Handler);
				}
			}
		}
	};
	//---------------------------------------------------------
	// INIT: Class
	//---------------------------------------------------------
	this.InitializeClass = function () {
		this.Context = context ? context : self;
		this.Items = [];
		this.Add(this.Context, 'unload', new System.EventHandler(this, this.Dispose), false);
	};
	this.InitializeClass();
};
System.Type.RegisterClass("System.EventsManager", System.EventsManager);

// If script is not on server side then...
if (typeof Response !== "object") {
	var Events = new System.EventsManager();
	System.EventsManager.Current = new System.EventsManager();
}

//=============================================================================
// CLASS: Exceptions
//-----------------------------------------------------------------------------

// From MicrosoftAjax.debug.js
Error.create = function (message, errorInfo) {
	var err = new Error(message);
	err.message = message;
	if (errorInfo) {
		for (var v in errorInfo) {
			err[v] = errorInfo[v];
		}
	}
	err.popStackFrame();
	return err;
};

// From MicrosoftAjax.debug.js
Error.prototype.popStackFrame = function () {
	if (arguments.length !== 0) throw Error.parameterCount();
	if (typeof this.stack === "undefined" || this.stack === null ||
		typeof this.fileName === "undefined" || this.fileName === null ||
		typeof this.lineNumber === "undefined" || this.lineNumber === null) {
		return;
	}
	var stackFrames = this.stack.split("\n");
	var currentFrame = stackFrames[0];
	var pattern = this.fileName + ":" + this.lineNumber;
	while (typeof currentFrame !== "undefined" &&
		currentFrame !== null &&
		currentFrame.indexOf(pattern) === -1) {
		stackFrames.shift();
		currentFrame = stackFrames[0];
	}
	var nextFrame = stackFrames[1];
	if (typeof nextFrame === "undefined" || nextFrame === null) {
		return;
	}
	var nextFrameParts = nextFrame.match(/@(.*):(\d+)$/);
	if (typeof nextFrameParts === "undefined" || nextFrameParts === null) {
		return;
	}
	this.fileName = nextFrameParts[1];
	this.lineNumber = parseInt(nextFrameParts[2]);
	stackFrames.shift();
	this.stack = stackFrames.join("\n");
};

/// <summary>Initializes a new instance of the System.Exception class with a specified error message.</summary>
/// <param name="message">The message that describes the error.</param>
System.Exception = function (message) { };

/// <summary>Initializes a new instance of the System.Exception class.</summary>
System.Exception = function () {
	switch (arguments.length) {
		case 0:
			break;
		case 1:
			if (typeof arguments[0].GetType === "function") return arguments[0];
			this.message = arguments[0];
			break;
		case 2:
			break;
		default:
			break;
	}
	var err = Error.create(this.message, { name: this.GetType().FullName });
	err.popStackFrame();
	return err;
};
System.Type.RegisterClass("System.Exception", System.Exception);

System.ArgumentNullException = function (paramName, message) {
	/// <summary>
	/// Initializes an instance of the <see cref="T:System.ArgumentNullException" /> class with a specified error message and the name of the parameter that causes this exception.
	/// </summary>
	/// <param name="paramName" type="String" optional="true" mayBeNull="true">The name of the parameter that caused the exception.</param>
	/// <param name="message" type="String" optional="true" mayBeNull="true">A message that describes the error.</param>
	//---------------------------------------------------------
	this.message = "";
	this.message += message ? message : "Value cannot be null.";
	this.message += "\r\nParameter name: '" + paramName + "'";
	var err = Error.create(this.message, { name: this.GetType().FullName });
	err.popStackFrame();
	return err;
};
System.Type.RegisterClass("System.ArgumentNullException", System.ArgumentNullException);

System.ArgumentException = function (message, paramName) {
	/// <summary>
	/// Initializes a new instance of the <see cref="T:System.ArgumentException" /> class with a specified error message and the name of the parameter that causes this exception.
	/// </summary>
	/// <param name="message" type="String" optional="true" mayBeNull="true">The error message that explains the reason for the exception.</param>
	/// <param name="paramName" type="String" optional="true" mayBeNull="true">The name of the parameter that caused the current exception.</param>
	var base = new System.Type.Inherits(this, new System.Exception());
	this.message = "";
	this.message += message;
	this.message += paramName ? "\r\nParameter name: '" + paramName + "'" : "";
	var err = Error.create(this.message, { name: this.GetType().FullName });
	err.popStackFrame();
	return err;
};
System.Type.RegisterClass("System.ArgumentException", System.ArgumentException);

System.ObjectDisposedException = function (objectName, message) {
	/// <summary>
	/// Initializes a new instance of the <see cref="T:System.ObjectDisposedException" /> class with the specified object name and message.
	/// </summary>
	/// <param name="objectName"" type="String" optional="true" mayBeNull="true">The name of the disposed object.</param>
	/// <param name="message"" type="String" optional="true" mayBeNull="true">The error message that explains the reason for the exception.</param>
	var base = new System.Type.Inherits(this, new System.Exception());
	this.message = "";
	this.message += message ? message : "Cannot access a disposed object.";
	this.message += "\r\nObject name: '" + objectName + "'";
	var err = Error.create(this.message, { name: this.GetType().FullName });
	err.popStackFrame();
	return err;
};
System.Type.RegisterClass("System.ObjectDisposedException", System.ObjectDisposedException);

System.Class.ExceptionToString = function (ex) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns>void</returns>
	// If this is server side;
	var ex1 = new System.Exception(ex);
	var errorString = "";
	if (typeof Response === "object") {
		// ex.name;
		errorString = "Error: Exception[number=" + ex1.number + "; name='" + ex1.GetType().FullName + "'; message='" + ex1.message + "'; description='" + ex1.description + "']";
	} else {
		errorString = "Error: Exception[result=" + ex1.result + "; name='" + ex1.GetType().FullName + "'; message='" + ex1.message + "']";
	}
	return errorString;
};

System.Class.ExceptionToTrace = function (ex) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns>void</returns>
	Trace.Write(System.Class.ExceptionToString(ex));
};

System.Class.Properties = {};

System.Class.Properties.ToString = function (object) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns type="String" />
	var results = "";
	results += typeof object + " properties:\r\n";
	for (var property in object) {
		var valueType = typeof object[property];
		var value = object[property];
		results += valueType + " " + property + " = " + value + "\r\n";
	}
	return results;
};

System.Class.Properties.ToTrace = function (object, name, recursive, levels) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns>void</returns>
	//var testClass = {};
	//var type = object.Type ? object.Type : ""
	if (typeof object === "object" && typeof name === "undefined") {
		try {
			name = new String(object);
		} catch (ex) {
			System.Class.ExceptionToTrace(ex);
		}
	}
	// By default go 2 levels inside;
	if (typeof levels === "undefined") levels = 3;
	if (recursive === false) levels = 0;
	//if (name != null) Trace.Write(name+" { "+"<font color=\"gray\"> = "+new String(object)+"</font>");
	try {
		Trace.LevelUpdate(1);
		for (var property in object) {
			var text = "." + property;
			if (typeof object[property] === "string") {
				text += "<font color=\"gray\"> = '" + object[property] + "'</font>";
			} else {
				text += "<font color=\"gray\"> = " + object[property] + "</font>";
			}
			if (levels > 1) {
				var goInside = typeof object[property] === "object" || property === "prototype" || property === "superclass";
				if (object[property] === null) goInside = false;
				if (goInside) {
					var childName = "." + property;
					var childLevels = levels - 1;
					Trace.Write(text + " {", 1);
					System.Class.ListProperties(object[property], childName, true, childLevels);
					Trace.Write("}", -2);
				} else {
					Trace.Write(text);
				}
			}
		}
	} catch (ex) {
		//Trace.Write("Error: "+ex.message);
		//System.Class.ExceptionToTrace(ex);
	}
	Trace.LevelUpdate(-1);
	if (name !== null) Trace.Write("}");
};

System.Class.ListProperties = function (object, name, recursive, levels) {
	/// <summary>
	/// Outdated: Use System.Class.Properties.ToTrace
	/// </summary>
	/// <returns>void</returns>
	System.Class.Properties.ToTrace(object, name, recursive, levels);
};

//=============================================================================
// System.Parse
//-----------------------------------------------------------------------------

System.Parse = function (object, value) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns type="Object" />
	var results = null;
	switch (typeof object) {
		case "boolean":
			results = System.Bool.Parse(value);
			break;
		case "number":
			results = parseFloat(value);
			break;
		case "string":
			results = value;
			//if (object == "Guid"){
			//}
			break;
		case "object":
			results = value;
			// If this is Date.
			if (typeof object["getDate"] === "function") {
				results = new Date().GetFromString(value);
			}
			break;
		default:
			results = value;
			//alert("number: "+value+" - "+results);
			break;
	}
	return results;
};

//=============================================================================
// System.Bool
//-----------------------------------------------------------------------------

System.Bool = function () { };
System.Type.RegisterClass("System.Bool", System.Bool);

System.Bool.Parse = function (value) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns type="Boolean"></returns>
	var results = new String(value).toLowerCase();
	if (results === "true" || results === "1" || results === "-1" || results === "on" || results === "yes") {
		results = true;
	} else {
		results = false;
	}
	return results;
};

System.Bool.IsBoolean = function (value) {
	/// <summary>
	/// Not a Number.
	/// </summary>
	/// <returns type="Boolean" />
	value = new String(value).toLowerCase();
	var results =
		value === "true" || value === "false" ||
		value === "1" || value === "0" ||
		value === "-1" ||
		value === "on" || value === "off" ||
		value === "yes" || value === "no";
	return results;
};

//=============================================================================
// System.Guid
//-----------------------------------------------------------------------------

System.Guid = function () {
	/// <summary>
	/// A read-only instance of the System.Guid class whose value is guaranteed to
	/// be all zeros.
	/// </summary>
};

System.Guid = function (g) {
	/// <summary>
	/// Initializes a new instance of the System.Guid class using the value represented
	/// by the specified string.
	/// </summary>
	/// <param name="g" type="String">
	/// A System.String that contains a GUID in one of the following formats ('d'
	/// represents a hexadecimal digit whose case is ignored): 32 contiguous digits:
	/// dddddddddddddddddddddddddddddddd -or- Groups of 8, 4, 4, 4, and 12 digits
	/// with hyphens between the groups. The entire GUID can optionally be enclosed
	/// in matching braces or parentheses: dddddddd-dddd-dddd-dddd-dddddddddddd -or-
	/// {dddddddd-dddd-dddd-dddd-dddddddddddd} -or- (dddddddd-dddd-dddd-dddd-dddddddddddd)
	/// -or- Groups of 8, 4, and 4 digits, and a subset of eight groups of 2 digits,
	/// with each group prefixed by "0x" or "0X", and separated by commas. The entire
	/// GUID, as well as the subset, is enclosed in matching braces: {0xdddddddd,
	/// 0xdddd, 0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} All braces, commas,
	/// and "0x" prefixes are required. All embedded spaces are ignored. All leading
	/// zeroes in a group are ignored.The digits shown in a group are the maximum
	/// number of meaningful digits that can appear in that group. You can specify
	/// from 1 to the number of digits shown for a group. The specified digits are
	/// assumed to be the low order digits of the group.
	/// </param>
};


System.Guid = function (b) {
	/// <summary>
	/// Initializes a new instance of the System.Guid class using the specified array
	/// of bytes.
	/// </summary>
	/// <param name="b" type="Byte[]">
	/// A 16 element byte array containing values with which to initialize the GUID.
	/// </param>
	this.Bytes = new Array;
	// Bytes array have different order as represented in hex string.
	this.ByteOrder = [3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15];
	//---------------------------------------------------------
	// METHOD: ToString.
	//---------------------------------------------------------
	this.ToString = function (format) {
		// Format (default is D):
		// N: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
		// D: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
		// B: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
		// P: (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
		format = format ? format : "D";
		var addHyphens = "DBP".indexOf(format) > -1;
		var guid = "";
		for (var i = 0; i < 16; i++) {
			if (addHyphens) guid += i === 4 || i === 6 || i === 8 || i === 10 ? "-" : "";
			var pos = this.ByteOrder[i];
			guid += this.numberToHex(this.Bytes[pos]);
		}
		if (format === "B") guid = "{" + guid + "}";
		if (format === "P") guid = "(" + guid + ")";
		return guid;
	};
	// Add automatic conversion to string in javascript.
	// For example Response.Write(guid) instead of Response.Write(guid.ToString());
	this.toString = this.ToString;
	//---------------------------------------------------------
	// METHOD: ToByteArray
	//---------------------------------------------------------
	this.ToByteArray = function () {
		return this.Bytes;
	};
	//---------------------------------------------------------
	// METHOD: Equals
	//---------------------------------------------------------
	this.Equals = function (value) {
		var guid = value;
		var results = true;
		if (typeof value !== "object") {
			guid = new System.Guid(value);
		}
		// Compare;
		for (var i = 0; i < 16; i++) {
			if (this.Bytes[i] !== guid.Bytes[i]) {
				results = false;
				break;
			}
		}
		return results;
	};
	//---------------------------------------------------------
	// PRIVATE METHOD: numberToHex
	//---------------------------------------------------------
	this.numberToHex = function (value) {
		var hex = value <= 0xF ? "0" : "";
		hex += value.toString(16);
		return hex;
	};
	//---------------------------------------------------------
	// PRIVATE METHOD: stringToHexes
	//---------------------------------------------------------
	this.GuidStringToBytes = function (value) {
		// Strip separators.
		var regExp = new RegExp("[{}\(\)-]", "g");
		var guid = value.replace(regExp, "");
		// Convert Hex string to bytes.
		var bytes = [];
		for (var i = 0; i < 16; i++) {
			var pos = this.ByteOrder[i];
			var b1 = guid.charAt(pos * 2);
			var b2 = guid.charAt(pos * 2 + 1);
			bytes.push(unescape("%" + b1 + b2).charCodeAt(0));
		}
		return bytes;
	};
	//---------------------------------------------------------
	// INIT: Initialize class.
	//---------------------------------------------------------
	this.InitializeClass = function () {
		this.Bytes = [];
		// Create guid by type of value.
		var a0 = arguments[0];
		var i;
		switch (typeof a0) {
			case "null":
				for (i = 0; i < 16; i++) this.Bytes.push(0);
				break;
			case "undefined":
				for (i = 0; i < 16; i++) this.Bytes.push(0);
				break;
			case "string":
				this.Bytes = this.GuidStringToBytes(a0);
				break;
			case "object":
				if (a0.GetType && a0.GetType().FullName === "System.Guid") {
					// Treat as another guid.
					for (i = 0; i < 16; i++) {
						this.Bytes.push(a0.Bytes[i]);
					}
				} else {
					// Get first 16 elements of array as bytes.
					for (i = 0; i < 16; i++) {
						this.Bytes.push(a0[i]);
					}
				}
				break;
			default:
				break;
		}
	};
	this.InitializeClass.apply(this, arguments);
};
System.Type.RegisterClass("System.Guid", System.Guid);

System.Guid.Empty = new System.Guid("00000000-0000-0000-0000-000000000000");

System.Guid.NewGuid = function () {
	/// <summary>
	/// Initializes a new instance of the System.Guid class.
	/// </summary>
	/// <returns type="System.Guid">
	/// A new System.Guid object.
	/// </returns>
	// Create random guid.
	var bytes = [];
	for (var i = 0; i < 16; i++) {
		// Push random number [0-FF].
		var dec = Math.floor(Math.random() * 0xFF);
		bytes.push(dec);
	}
	var guid = new System.Guid(bytes);
	return guid;
};

//=============================================================================
// System.Math
//-----------------------------------------------------------------------------

System.Math = System.Math ? System.Math : {};

System.Math.ShiftRight = function (number, positions) {
	/// <summary>
	/// Shifts the values of the bits to the right (arithmetic shift '>>').
	/// </summary>
	/// <remarks>
	/// JavaScript can store whole numbers properly with 52 bit precision only.
	/// 0xFFFFFFFFFFFFF. Any numbers larger than that will be f**ked during
	/// conversions. For examle: 0xEFFFFFFFFFFFFF = 67553994410557439,
	/// but output of Document.Write(0xEFFFFFFFFFFFFF) will be 67553994410557440
	/// </remarks>
	var h = Math.pow(2, positions);
	var d = number & h - 1;
	var n = number - d;
	return n / h;
};

System.Math.ShiftLRight = function (number, positions) {
	/// <summary>
	/// Shifts the values of the bits to the right (logical shift '>>').
	/// </summary>
	/// <remarks>
	var h = Math.pow(2, positions);
	var d = number & h - 1;
	var n = number - d;
	return n / h;
};

System.Math.ShiftLeft = function (number, positions) {
	/// <summary>
	/// Shifts the values of the bits to the left (arithmetic shift '<<').
	/// </summary>
	return number * Math.pow(2, positions);
};

//=============================================================================
// Random
//-----------------------------------------------------------------------------

System.Random = function () {
	/// <summary>
	/// Initializes a new instance of the Random class, using a time-dependent default
	/// seed value.
	/// </summary>
	//---------------------------------------------------------
	this.Next = function (maxValue) {
		/// <summary>
		/// Returns a nonnegative random number less than the specified maximum.
		/// </summary>
		/// <param type="int" name="maxValue">
		/// The exclusive upper bound of the random number returned. maxValue must be
		/// greater than or equal to zero.
		/// </param>
		/// <returns>
		/// A 32-bit signed integer greater than or equal to zero, and less than maxValue;
		/// that is, the range of return values includes zero but not maxValue.
		/// </returns>
	};
	//---------------------------------------------------------
	this.Next = function (minValue, maxValue) {
		/// <summary>
		/// Returns a random number within a specified range.
		/// </summary>
		/// <param type="int" name="minValue">
		/// The inclusive lower bound of the random number returned.
		/// </param>
		/// <param type="int" name="maxValue">
		///  The exclusive upper bound of the random number returned. maxValue must be
		///  greater than or equal to minValue.
		/// </param>
		/// <returns>
		/// A 32-bit signed integer greater than or equal to minValue and less than maxValue;
		/// If minValue equals maxValue, minValue is returned.
		/// </returns>
		//---------------------
		// Math.random() Generates a number from 0 to slightly less than 1 (shown as <1).
		// This is perfectly random because each number will appear the same number of times.
		// Process arguments.
		switch (arguments.length) {
			case 0:
				maxValue = Math.pow(2, 31);
				minValue = 0;
				break;
			case 1:
				maxValue = arguments[0];
				minValue = 0;
				break;
			case 2:
				break;
			default:
				return 0;
		}
		var number = minValue;
		if (maxValue > minValue) {
			number = Math.floor(Math.random() * (maxValue - minValue)) + minValue;
		}
		return number;
	};
	//---------------------------------------------------------
	this.NextBytes = function (buffer) {
		/// <summary>
		/// Fills the elements of a specified array of bytes with random numbers.
		/// </summary>
		/// <param type="byte[]" name="buffer">
		/// An array of bytes to contain random numbers.
		/// </param>
		/// <returns>
		///  An array of bytes to contain random numbers.
		/// </returns>
		/// <remarks>
		/// Each element of the array of bytes is set to a random number greater than or equal to zero, and less than or equal to 255 (hexadecimal 0xFF).
		/// </remarks>
		//---------------------
		var length = buffer.length;
		for (var i = 0; i < length; i++) {
			buffer[i] = this.Next(0, 256);
		}
		return buffer;
	};
	//---------------------------------------------------------
	this.InitializeClass = function () {
	};
	this.InitializeClass.apply(this, arguments);
};
System.Type.RegisterClass("System.Random", System.Random);


//=============================================================================
// System.Char
//-----------------------------------------------------------------------------

System.Char = function () { };
System.Type.RegisterClass("System.Char", System.Char);

//=============================================================================
// System.TimeSpan
//-----------------------------------------------------------------------------

// Examples:
//
// Add 84 milliseconds:
// var span = new System.TimeSpan(84);
//
// Add 5 hours, 7 minutes, 10 seconds, and 0 milliseconds:
// var span = new System.TimeSpan(5,7,10,0);
//
// var dateStart = new Date();
// ...run some process here...
// var dateEd = new Date();
// var span = new System.TimeSpan(dateEd.getTime() - dateStart.getTime());
//

System.TimeSpan = function () {
	/// <summary>
	/// 
	/// </summary>
	//---------------------------------------------------------
	// Public properties.:
	//---------------------------------------------------------
	// Same as total milliseconds.
	this.Ticks = 0;
	// Span Values.
	this.Milliseconds = 0;
	this.Seconds = 0;
	this.Minutes = 0;
	this.Hours = 0;
	this.Days = 0;
	// Total Values.
	this.TotalMilliseconds = 0;
	this.TotalSeconds = 0;
	this.TotalMinutes = 0;
	this.TotalHours = 0;
	this.TotalDays = 0;
	//---------------------------------------------------------
	// Private properties.:
	//---------------------------------------------------------
	var me = this;
	//---------------------------------------------------------
	// PRIVATE METHOD: addValues
	//---------------------------------------------------------
	function addValues() {
		//Trace.Write(arguments.length);
		var args = ["Days", "Hours", "Minutes", "Seconds", "Milliseconds"];
		var j = arguments.length;
		for (var i = 0; i < j; i++) {
			var step = args.length - arguments.length;
			//Trace.Write(args[step+i]+" = "+arguments[i]);
			this[args[step + i]] = arguments[i];
		}
		normalizeValues();
		updateTicksAndTotals();
	}
	//---------------------------------------------------------
	// PRIVATE METHOD: updateTotals
	//---------------------------------------------------------
	function normalizeValues() {
		var tmpVal = 0;
		var tmpAdd = 0;
		// Normalize milliseconds.
		tmpVal = me.Milliseconds % 1000;
		tmpAdd = (me.Milliseconds - tmpVal) / 1000;
		me.Milliseconds = tmpVal;
		me.Seconds += tmpAdd;
		// Normalize seconds.
		tmpVal = me.Seconds % 60;
		tmpAdd = (me.Seconds - tmpVal) / 60;
		me.Seconds = tmpVal;
		me.Minutes += tmpAdd;
		// Normalize Minutes.
		tmpVal = me.Minutes % 60;
		tmpAdd = (me.Minutes - tmpVal) / 60;
		me.Minutes = tmpVal;
		me.Hours += tmpAdd;
		// Normalize Hours.
		tmpVal = me.Hours % 24;
		tmpAdd = (me.Hours - tmpVal) / 24;
		me.Hours = tmpVal;
		me.Days += tmpAdd;
		//Trace.Write("Nms: "+me.Milliseconds);
		//Trace.Write("Nss: "+me.Seconds);
		//Trace.Write("Nmm: "+me.Minutes);
		//Trace.Write("Nhh: "+me.Hours);
		//Trace.Write("Ndd: "+me.Days);
	}
	//---------------------------------------------------------
	// PRIVATE METHOD: resetValues
	//---------------------------------------------------------
	function resetValues() {
		me.Ticks = 0;
		me.Milliseconds = 0;
		me.Seconds = 0;
		me.Minutes = 0;
		me.Hours = 0;
		me.Days = 0;
		me.TotalMilliseconds = 0;
		me.TotalSeconds = 0;
		me.TotalMinutes = 0;
		me.TotalHours = 0;
		me.TotalDays = 0;
	}
	//---------------------------------------------------------
	// PRIVATE METHOD: updateTotals
	//---------------------------------------------------------
	function updateTicksAndTotals() {
		var tmp = me.Days * 24; // Result: hours.
		tmp = (tmp + me.Hours) * 60; // Result: minutes.
		tmp = (tmp + me.Minutes) * 60; // Result: seconds.
		me.Ticks = (tmp + me.Seconds) * 1000 + me.Milliseconds; // Result: milliseconds.
		me.TotalMilliseconds = me.Ticks;
		me.TotalSeconds = me.TotalMilliseconds / 1000;
		me.TotalMinutes = me.TotalSeconds / 60;
		me.TotalHours = me.TotalMinutes / 60;
		me.TotalDays = me.TotalHours / 24;
		//Trace.Write("Tck: "+me.Ticks);
		//Trace.Write("Tms: "+me.TotalMilliseconds);
		//Trace.Write("Tss: "+me.TotalSeconds);
		//Trace.Write("Tmm: "+me.TotalMinutes);
		//Trace.Write("Thh: "+me.TotalHours);
		//Trace.Write("Tdd: "+me.TotalDays);
	}
	//---------------------------------------------------------
	// METHOD: Add
	//---------------------------------------------------------
	this.Add = function () {
		var span = arguments[0];
		//Trace.Write(typeof(arguments[0]));
		if (typeof arguments[0] === "number") {
			span = new System.TimeSpan.apply(this, arguments);
		}
		var ticks = this.Ticks + span.Ticks;
		var newSpan = new System.TimeSpan(ticks);
		return newSpan;
	};
	//---------------------------------------------------------
	// METHOD: Subtract
	//---------------------------------------------------------
	this.Subtract = function () {
		var span = arguments[0];
		if (typeof arguments[0] === "number") {
			span = new System.TimeSpan.apply(this, arguments);
		}
		var ticks = this.Ticks - span.Ticks;
		var newSpan = new System.TimeSpan(ticks);
		return newSpan;
	};
	//---------------------------------------------------------
	// METHOD: ToString
	//---------------------------------------------------------
	this.ToString = function (format) {
		var results = "";
		var sDays = format === "X" ? " days " : " ";
		var sHours = format === "X" ? " hours " : ":";
		var sMinutes = format === "X" ? " min " : ":";
		var sSeconds = format === "X" ? " sec" : "";
		if (this.TotalDays >= 1 || format === "F") results += this.Days + sDays;
		results += (this.Hours < 10 ? "0" : "") + this.Hours + sHours;
		results += (this.Minutes < 10 ? "0" : "") + this.Minutes + sMinutes;
		results += (this.Seconds < 10 ? "0" : "") + this.Seconds + sSeconds;
		if (format === "F") results += "." + this.Milliseconds;
		return results;
	};
	this.toString = this.ToString;
	//---------------------------------------------------------
	// INIT: Class
	//---------------------------------------------------------
	this.InitializeClass = function () {
		addValues.apply(this, arguments);
	};
	this.InitializeClass.apply(this, arguments);
};
System.Type.RegisterClass("System.TimeSpan", System.TimeSpan);

System.TimeSpan.TicksPerMillisecond = 1;

//=============================================================================
// System.Buffer
//-----------------------------------------------------------------------------

System.Array = function () {
	//---------------------------------------------------------
	this.Initialize = function () {
	};
	this.Initialize.apply(this, arguments);
};
System.Type.RegisterClass("System.Array", System.Array);

// Add static method.
System.Array.Reverse = function (array, index, length) {
	/// <summary>
	/// Reverses the sequence of the elements in a range of elements in the one-dimensional
	/// </summary>
	/// <param name="array">The one-dimensional System.Array to reverse.</param>
	/// <param name="index">The starting index of the section to reverse.</param>
	/// <param name="length">The number of elements in the section to reverse.</param>
	index = index ? index : 0;
	length = length ? length : array.length;
	// Make a copy of reversed block.
	var iArray = array.slice(index, index + length).reverse();
	for (var i = 0; i < length; i++) array[i + index] = iArray[i];
};

// Add static method.
System.Array._Copy1 = function (sourceArray, destinationArray, length) {
	/// <summary>
	/// Copy array
	/// </summary>
	for (var i = 0; i < length; i++) {
		destinationArray[i] = sourceArray[i];
	}
};

// Add static method.
System.Array._Copy2 = function (sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
	/// <summary>
	/// Copy array
	/// </summary>
	for (var i = 0; i < length; i++) {
		destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
	}
};

System.Array.Copy = function () {
	if (arguments.length === 3) System.Array._Copy1.apply(this, arguments);
	if (arguments.length === 5) System.Array._Copy2.apply(this, arguments);
};

System.Array.FillMultiDimensional = function (array, dimensions, value) {
	var x;
	if (dimensions.length > 0) {
		for (x = 0; x < array.length; x++) {
			var ar = new Array(dimensions[0]);
			var dims = dimensions.slice(1);
			System.Array.FillMultiDimensional(ar, dims, value);
			array[x] = ar;
		}
	} else {
		// if this array is placed at last level.
		for (x = 0; x < array.length; x++) {
			// set default value.
			array[x] = value;
		}
	}
	return array;
};

System.Array.GetMultiDimensional = function (dimensions, value) {
	/// <sumary>
	/// Get multi-dimensional array with default values.
	/// </summary>
	/// <param name="dimensions" type="int[]">List of dimension sizes.</param>
	/// <param name="value">Default value of array.</param>
	/// <example>
	/// Get 16x16 array filled with zeroes.
	/// var matrix = System.Array.GetMultiDimensional([16,16] ,0);
	/// </example>
	var array = new Array(dimensions[0]);
	return System.Array.FillMultiDimensional(array, dimensions.slice(1), value);
};
System.Array.Clear = function (array, index, length) {
	/// <sumary>
	/// Zeroize array.
	/// </summary>
	for (var i = 0; i < length; i++) array[i + index] = 0;
};


System.Array.SortComparer = function (index, direction) {
	var d = direction ? [-1, 1] : [1, -1];
	return function (a, b) {
		return a[index] === b[index]
			? 0 : a[index] < b[index]
				? d[0] : d[1];
	};
};

System.Array.Sort = function (array, index, direction) {
	/// <sumary>
	/// Sort array.
	/// </summary>
	/// <param name="array" type="Array">two-dimentional array or one-dimentional array of objects</param>
	/// <param name="index">Index or column name.</param>
	/// <param name="direction">Sort direction. True - ascending; False - descending.</param>
	direction = direction === false ? false : true;
	array.sort(System.Array.SortComparer(index, direction));
};

System.Array.Resize = function (array, newSize, defaultValue) {
	/// <sumary>Resize array.</summary>
	if (typeof defaultValue === "undefined")
		defaultValue = 0;
	while (newSize > array.length)
		array.push(defaultValue);
	array.length = newSize;
};

//=============================================================================
// System.Buffer
//-----------------------------------------------------------------------------

System.Buffer = function () {
	//---------------------------------------------------------
	this.Initialize = function () {
	};
	this.Initialize.apply(this, arguments);
};
System.Type.RegisterClass("System.Buffer", System.Buffer);

// Add static method.
System.Buffer.BlockCopy = function (src, srcOffset, dst, dstOffset, count) {
	/// <summary>
	/// Copies a specified number of bytes from a source array starting at a particular
	/// offset to a destination array starting at a particular offset.
	/// </summary>
	/// <param name="src">The source buffer.</param>
	/// <param name="srcOffset">The byte offset into src.</param>
	/// <param name="dst">The destination buffer.</param>
	/// <param name="dstOffset">The byte offset into dst.</param>
	/// <param name="count">The number of bytes to copy.</param>
	for (var i = 0; i < count; i++) {
		dst[dstOffset + i] = src[srcOffset + i];
	}
};

//=============================================================================
// System.Byte[]
//-----------------------------------------------------------------------------

System.Byte = function () {
	/// <summary>
	/// Get array of bytes.
	/// </summary>
	/// <example>
	/// To get one-dimentional array:
	///     var bytes = new System.Bytes(16);
	/// To get multi-dimentional array:
	///     var x = 3; y = 5; z = 2; ...
	///     var bytes = new System.Bytes(x, y, z, ...);
	/// To get value from multi-dimentional array:
	///     var value = bytes[0][2][1];
	/// It's same as in C#
	/// </example>
	// Convert arguments to dimensions array.
	var dims = [];
	for (var i = 0; i < arguments.length; i++) {
		dims.push(arguments[i]);
	}
	// Return multi-dimensional array filled with zero.
	return System.Array.GetMultiDimensional(dims, 0);
};
System.Type.RegisterClass("System.Byte", System.Byte);

//=============================================================================
// System.Int32
//-----------------------------------------------------------------------------

System.Int32 = function (value) {
	/// <summary>
	/// 
	/// </summary>
	this.Int = 0;
	this.DefaultFormat = "";
	//---------------------------------------------------------
	// METHOD: ToString
	//---------------------------------------------------------
	this.ToString = function (format) {
		var converted = "";
		switch (format) {
			case "B":
				if (this.Int >= 1048576) {
					converted = Math.round(this.Int / 1048576 * 10) / 10 + " MB";
				} else if (this.Int >= 1024) {
					converted = Math.round(this.Int / 1024 * 10) / 10 + " KB";
				} else {
					converted = new String(this.Int);
				}
				break;
			case "X2":
			case "X4":
			case "X6":
			case "X8":
				var hex = this.Int.toString(16);
				var len = parseInt(format.substr(1));
				var pfx = "00000000".substr(0, len);
				converted = pfx.substr(0, len - hex.length) + hex;
				break;
			default:
				converted = new String(this.Int);
				break;
		}
		return converted;
	};
	//---------------------------------------------------------
	// INIT: Class
	//---------------------------------------------------------
	this.InitializeClass = function () {
		this.Int = parseInt(value);
		this.DefaultFormat = "";
	};
	this.InitializeClass();
};
System.Type.RegisterClass("System.Int32", System.Int32);

//=============================================================================
// System.UInt32
//-----------------------------------------------------------------------------

// Unsigned 32-bit integer: 0 to 4,294,967,295 [0x00000000 - 0xFFFFFFFF]
System.UInt32 = System.Byte;
System.Int16 = System.Byte;
System.UInt16 = System.Byte;

//=============================================================================
// System.DateTime
//-----------------------------------------------------------------------------

//System.DateTime.ExpressionISO = new RegExp("([1-9][1-9][1-9][1-9])-([1-9][0-9])-([0-9][0-9])T([0-9][0-9]):([0-9][0-9]):([0-9][0-9]):([0-9][0-9]).*");

System.DateTime = function (year, month, day, hour, minute, second, millisecond) {
	/// <summary>
	/// System.DateTime class. Some methods will be applied to JavaScript Date object.
	/// </summary>
	//	this.DefaultFormat = "";
	//	this.Date = new Date;
	//	//---------------------------------------------------------
	//	this.addZero = function (number) {
	//		/// <summary>
	//		/// Add leading zero to number in forder to format date properly.
	//		/// </summary>
	//		return (number < 10) ? '0' + number : number;
	//	}
	//	//---------------------------------------------------------
	//	this.ToString = function (format) {
	//		// This function will be created by runing
	//		// System.Extensions.Apply() at the end of this script file.
	//	}
	//	//---------------------------------------------------------
	//	this.InitializeClass = function () {
	//		this.DefaultFormat = "YYYY-MM-DD HH:NN:SS";
	//		this.Date = date ? date : new Date;
	//	}
	//	this.InitializeClass();
	year = year === null ? 0 : year;
	month = month === null ? 1 : month;
	day = day === null ? 1 : day;
	hour = hour === null ? 0 : hour;
	minute = minute === null ? 0 : minute;
	second = second === null ? 0 : second;
	millisecond = millisecond === null ? 0 : millisecond;
	var d = new Date(year, month - 1, day, hour, minute, second, millisecond);
	return d;
};
System.Type.RegisterClass("System.DateTime", System.DateTime);

// Create public static method System.DateTime.Now.ToString();

System.DateTime.Now = function () {
	/// <summary>
	/// Gets a DateTime object that is set to the current date and time on this computer,
	/// expressed as the local time.
	/// </summary>
	return new Date();
};

System.DateTime.UtcNow = function () {
	/// <summary>
	/// Gets a DateTime object that is set to the current date and time on this computer,
	/// expressed as the Coordinated Universal Time (UTC).
	/// </summary>
	var now = new Date();
	var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
	return utc;
};

System.DateTime.ToUniversalTime = function () {
	/// <summary>
	/// Gets a DateTime object that is set to the current date and time on this computer,
	/// expressed as the Coordinated Universal Time (UTC).
	/// </summary>
	/// <remarks>
	/// There is no native support for most of DateTime localization methods in JavaScript (like DateTimeKind enum in C#).
	/// This means that "System.DateTime.UtcNow.ToUniversalTime" will produce different results in C# and JavaScript.
	/// </remarks>
	var d = this;
	var utc = new Date(d.getTime() + d.getTimezoneOffset() * 60000);
	return utc;
};

//System.DateTime._minDate = -8640000000000000;
System.DateTime._jsZero = 62135596800000;

/// <summary>
/// DateTime regular expressions.
/// </summary>
System.DateTime.Expressions = {
	Default: new RegExp("(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/([0-9][0-9])"),
	UtcDate: new RegExp("([0-9][0-9][0-9][0-9])-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"),
	UtcTime: new RegExp("([01][0-9]|[2][0123]):([012345][0-9]):([012345][0-9])"),
	UtcMs: new RegExp("\.([0-9]+)"),
	Zone: new RegExp("([+-])([01][0-9]|[2][0123]):([012345][0-9])"),
	Utc: new RegExp("([0-9][0-9][0-9][0-9])-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])" + "[T ]" + "([01][0-9]|[2][0123]):([012345][0-9]):([012345][0-9])")
};

// Outdated: must be updated.
System.DateTime.Expression = new RegExp("(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/([0-9][0-9])");
System.DateTime.ExpressionUtcDate = new RegExp("([0-9][0-9][0-9][0-9])-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])");
System.DateTime.ExpressionUtcTime = new RegExp("([01][0-9]|[2][0123]):([012345][0-9]):([012345][0-9])");
System.DateTime.ExpressionUtcMs = new RegExp("\.([0-9]+)");
System.DateTime.ExpressionZone = new RegExp("([+-])([01][0-9]|[2][0123]):([012345][0-9])");
System.DateTime.ExpressionUtc = new RegExp(System.DateTime.ExpressionUtcDate.toString() + "[T ]" + System.DateTime.ExpressionUtcTime.toString());

System.DateTime.Subtract = function (value) {
	/// <summary>
	/// Subtract date.
	/// </summary>
	/// <returns type="System.TimeSpan" />
	//var span = arguments[0];
	//if (typeof (arguments[0]) == "number") {
	//	span = new System.TimeSpan.apply(this, arguments);
	//}
	//var ticks = this.Ticks - span.Ticks;
	//var newSpan = new System.TimeSpan(ticks);
	//return newSpan;
	var diff = this.getTime() - value.getTime() + System.DateTime._jsZero;
	return diff;
};

System.DateTime.Ticks = function () {
	var d = this;
	var diff = Date.UTC(
		d.getFullYear(),
		d.getMonth(),
		d.getDate(),
		d.getHours(),
		d.getMinutes(),
		d.getSeconds(),
		d.getMilliseconds()
	) + System.DateTime._jsZero;
	return diff;
};

System.DateTime.SubtractDays = function (days, round) {
	/// <summary>
	/// 
	/// </summary>
	date = this;
	var newDate = new Date(date - new System.TimeSpan(days, 0, 0, 0, 0).Ticks);
	// crop hours, minutes seconds.
	var nDate = newDate;
	if (round) {
		nDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate());
	}
	return nDate;
};

System.DateTime.SubtractMonths = function (months, round) {
	/// <summary>
	/// 
	/// </summary>
	date = this;
	var totalMonths = date.getFullYear() * 12 + date.getMonth();
	totalMonths = totalMonths - months;
	var newYear = Math.floor(totalMonths / 12);
	var newMonth = totalMonths - newYear * 12;
	date.setFullYear(newYear);
	date.setMonth(newMonth);
	var newDate = date;
	// Crop hours, minutes seconds.
	if (round) {
		newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
	}
	return newDate;
};

System.DateTime.GetFromString = function (dateString, ignoreTimeZoneAndParseAsUtc) {
	/// <summary>
	/// 
	/// </summary>
	date = this;
	// extract variable;
	var yyyy = 0;
	var MM = 0;
	var dd = 0;
	var dateMatch = dateString.match(System.DateTime.ExpressionUtcDate);
	if (dateMatch) {
		yyyy = dateMatch[0].replace(System.DateTime.ExpressionUtcDate, "$1");
		MM = dateMatch[0].replace(System.DateTime.ExpressionUtcDate, "$2");
		dd = dateMatch[0].replace(System.DateTime.ExpressionUtcDate, "$3");
	}
	var hh = 0;
	var mm = 0;
	var ss = 0;
	var timeMatch = dateString.match(System.DateTime.ExpressionUtcTime);
	if (timeMatch) {
		hh = timeMatch[0].replace(System.DateTime.ExpressionUtcTime, "$1");
		mm = timeMatch[0].replace(System.DateTime.ExpressionUtcTime, "$2");
		ss = timeMatch[0].replace(System.DateTime.ExpressionUtcTime, "$3");
	}
	var fff = 0;
	var msMatch = dateString.match(System.DateTime.ExpressionUtcMs);
	if (msMatch) {
		fff = msMatch[0].replace(System.DateTime.ExpressionUtcMs, "$1");
		fff = parseFloat("0." + fff);
		fff = parseInt(fff * 1000);
	}
	var znMatch = dateString.match(System.DateTime.ExpressionZone);
	var zn = 0;
	var zh = 0;
	var zm = 0;
	if (znMatch) {
		zn = parseInt(parseFloat(znMatch[0].replace(System.DateTime.ExpressionZone, "$1") + "1"));
		zh = parseInt(parseFloat(znMatch[0].replace(System.DateTime.ExpressionZone, "$2")) * zn);
		zm = parseInt(parseFloat(znMatch[0].replace(System.DateTime.ExpressionZone, "$3")) * zn);
	}
	if (ignoreTimeZoneAndParseAsUtc) {
		date.setUTCFullYear(yyyy, MM - 1, dd);
		date.setUTCHours(hh, mm, ss, fff);
	} else {
		// Check for marks which are same as "+00:00".
		var zeroZone = false;
		zeroZone = zeroZone || dateString.indexOf("GMT") > -1;
		zeroZone = zeroZone || dateString.indexOf("Z") > -1;
		// If timezone was not specified then treat string as local time.
		// This is default behaviour on all platforms.
		if (zn === 0 && !zeroZone) {
			date.setFullYear(yyyy, MM - 1, dd);
			date.setHours(hh, mm, ss, fff);
		} else {
			// Time zone was specified so we can use time zone.
			date.setUTCFullYear(yyyy, MM - 1, dd);
			date.setUTCHours(hh, mm, ss, fff);
			// This date contains time zone.
			date = new Date(date.getTime() - (zh * 60 + zm) * 60 * 1000);
		}
	}
	//alert(zn+":"+zh+":"+zm);
	return date;
};

System.DateTime.GetFromUtcString = function (dateString) {
	/// <summary>
	/// Gets Date from UTC string
	/// </summary>
	date = this;
	date.GetFromString(dateString, true);
	return date;
};


System.DateTime.ToString = function (format) {
	/// <summary>
	/// Converts the value of this instance to its equivalent string representation
	/// using the specified format.
	/// </summary>
	/// <param name="format" type="String">A format string.</param>
	/// <returns>A string representation of value of this instance as specified by format.</returns>
};

System.DateTime.ToString = function (dateTime, format) {
	/// <summary>
	/// Converts DateTime to its equivalent string representation
	/// using the specified format.
	/// </summary>
	/// <param name="dateTime" type="DateTime">DateTime.</param>
	/// <param name="format" type="String">A format string.</param>
	/// <returns>A string representation of value of this instance as specified by format.</returns>
	//---------------------------------------------------------
	// INIT: Arguments
	//---------------------------------------------------------
	var date;
	switch (arguments.length) {
		case 0:
			date = this;
			format = date.DefaultFormat;
			break;
		case 1:
			date = this;
			format = arguments[0];
			break;
		case 2:
			date = arguments[0];
			format = arguments[1];
			break;
		default:
			return "";
	}
	//---------------------------------------------------------
	//ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxfund/html/98b374e3-0cc2-4c78-ab44-efb671d71984.htm
	date.addZero = function (number) { return number < 10 ? '0' + number : number; };
	// www is provided for old compatibility. Use 'dddd' and 'ddd' instead.
	var wwwArray = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
	var dddArray = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
	var ddddArray = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thuesday", "Friday", "Saturday");
	var MMMArray = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	if (format === null) { format = date.DefaultFormat; }
	// "X" format is used to store DateTome values inside XML files of DataSet.
	if (format === "Outlook") {
		var now = new Date();
		if (date.getFullYear() === now.getFullYear()
			&& date.getMonth() === now.getMonth()
			&& date.getDate() === now.getDate()) {
			results = "ddd HH:mm";
		} else {
			format = "yyyy-MM-dd HH:mm";
		}
	}
	if (format === "X") { format = "yyyy-MM-ddTHH:mm:ss.fffzzz"; }
	// Generate values from Date.
	var fff = date.getMilliseconds();
	var yyyy = date.getFullYear();
	var yy = new String(date.addZero(yyyy));
	yy = yy.substr(yy.length - 2, 2);
	var www = wwwArray[date.getDay()]; // Outdated!!!
	var dddd = ddddArray[date.getDay()];
	var ddd = dddArray[date.getDay()];
	var dd = date.addZero(date.getDate());
	var MMM = MMMArray[date.getMonth()];
	var MM = date.addZero(date.getMonth() + 1);
	var hAmPm = date.getHours() % 12;
	if (hAmPm === 0) hAmPm = 12;
	var hh = date.addZero(hAmPm); // 12 format
	var HH = date.addZero(date.getHours()); // 24 format
	var mm = date.addZero(date.getMinutes());
	var ss = date.addZero(date.getSeconds());
	var tt = date.getHours() < 12 ? "AM" : "PM";
	var zzz = date.addZero(date.getTimezoneOffset());
	var offset = date.getTimezoneOffset();
	var negative = offset < 0;
	if (negative) offset = offset * -1;
	zzz = date.addZero(Math.floor(offset / 60)) + ":" + date.addZero(offset % 60);
	if (negative || offset === 0) {
		zzz = "+" + zzz;
	} else {
		zzz = "-" + zzz;
	}
	// Apply format.
	var strDate = new String(format);
	strDate = strDate.replace("yyyy", yyyy);
	strDate = strDate.replace("yy", yy);
	strDate = strDate.replace("www", www);
	strDate = strDate.replace(new RegExp("[d]{4-10}", "g"), dddd);
	strDate = strDate.replace(new RegExp("[d]{3}", "g"), ddd);
	strDate = strDate.replace("dd", dd);
	strDate = strDate.replace("MMM", MMM);
	strDate = strDate.replace("MM", MM);
	strDate = strDate.replace("ss", ss);
	strDate = strDate.replace("hh", hh);
	strDate = strDate.replace("HH", HH);
	strDate = strDate.replace("mm", mm);
	strDate = strDate.replace("ss", ss);
	strDate = strDate.replace("tt", tt);
	strDate = strDate.replace("ffffff", (fff + "000000").substr(0, 6));
	strDate = strDate.replace("fff", (fff + "000").substr(0, 3));
	strDate = strDate.replace("zzz", zzz);
	return strDate;
};

System.DateTime.ToUtcString = function (format) {
	/// <summary>
	/// Converts LocalTime to UTC String.
	/// </summary>
	/// <returns type="String" />
	var offset = this.getTime() + this.getTimezoneOffset() * 60000;
	var ss = new Date(offset);
	return ss.toString(format);
};

System.DateTime.ToDifferenceString = function (dateOld, dateNew) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns type="String" />
	this.addZero = function (number) { return number < 10 ? '0' + number : number; };
	dateNew = dateNew ? dateNew : new Date();
	var ms = dateNew.getTime() - dateOld.getTime();
	var nd = new Date(ms);
	var ph = nd.getHours();
	var pm = nd.getMinutes();
	var ps = nd.getSeconds();
	var msPassed = 1000 * (60 * (60 * ph + pm) + ps) + nd.getMilliseconds();
	var d = (nd.getTime() - msPassed) / 24 / 60 / 60 / 1000;
	var results = Math.round(d) + "d " + ph + "h " + pm + "m"; //+":"+this.addZero(ps);
	//	var ds = new String(d);
	//	if (d > 0){
	//		if (ds.substr(ds.length-1,ds.length) == "1"){
	//			 results = d+"d "+results;
	//		}else{
	//			 results = d+"d "+results;
	//		}
	//	}
	return results;
};

System.DateTime.GetDayType = function (d, trimResults) {
	d = d ? d : new Date();
	var results = "";
	//if (d.getMonth() === 8 && d.getDate() === 21) results = "New Year";
	if (d.getMonth() === 9 && d.getDate() === 31) results = "Halloween";
	if (d.getMonth() === 11 && d.getDate() === 31) results = "New Year";
	if (trimResults) {
		results = results.replace(" ", "");
	}
	return results;
};

//-------------------------------------------------------------
// Check DateTime
//-------------------------------------------------------------

System.DateTime.Separator = "/";
System.DateTime.YearMin = 1900;
System.DateTime.YearMax = 2100;
System.DateTime.DateFormat = "dd/mm/yyyy";
System.DateTime.Expression = new RegExp("(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/([0-9][0-9])");

System.DateTime.StripCharsInBag = function (s, bag) {
	/// <summary>
	/// 
	/// </summary>
	var returnString = "";
	// Search through string's characters one by one.
	// If character is not in bag, append to returnString.
	for (var i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (bag.indexOf(c) === -1) returnString += c;
	}
	return returnString;
};

System.DateTime.DaysInFebruary = function (valYear) {
	/// <summary>
	/// 
	/// </summary>
	// February has 29 days in any year evenly divisible by four,
	// EXCEPT for centurial years which are not also divisible by 400.
	return valYear % 4 === 0 && (!(valYear % 100 === 0) || valYear % 400 === 0) ? 29 : 28;
};

System.DateTime.DaysArray = function (valYear) {
	/// <summary>
	/// 
	/// </summary>
	var arrDays = new Array;
	for (var i = 1; i <= 12; i++) {
		arrDays[i] = 31;
		if (i === 4 || i === 6 || i === 9 || i === 11) { arrDays[i] = 30; }
	}
	// Set February days.
	arrDays[2] = System.DateTime.DaysInFebruary(valYear);
	return arrDays;
};

System.DateTime.IsDate = function (valDate) {
	/// <summary>
	/// 
	/// </summary>
	/// <returns type="bool" />
	var dateString = new String(valDate);
	results = "";
	// Get Day, Month, Year;
	if (!System.DateTime.Expression.test(dateString)) return "Invalid! <span style=\"color: gray;\">Format: mm/dd/yyyy</span>";
	// Date looks OK so continue to check.
	var MM = parseInt(dateString.replace(System.DateTime.Expression, "$1"), 10);
	var DD = parseInt(dateString.replace(System.DateTime.Expression, "$2"), 10);
	var YY = parseInt(dateString.replace(System.DateTime.Expression, "$3"), 10);
	//alert(DD+"/"+MM+"/"+YY);
	if (YY >= 0 && YY <= 50) YY += 2000;
	if (YY > 50 && YY <= 99) YY += 1900;
	var DaysInMonth = System.DateTime.DaysArray(YY)[MM];
	//alert(DD+"/"+MM+"/"+YY+" - "+DaysInMonth);
	if (MM < 1 || MM > 12) return "Invalid Month";
	if (DD > DaysInMonth) return "Invalid Day";
	if (YY < System.DateTime.YearMin || YY > System.DateTime.YearMax) return "Invalid Year";
	return results;
};

//-------------------------------------------------------------
// Extend JavaScript Date object.
//-------------------------------------------------------------

Date.prototype.GetFromString = System.DateTime.GetFromString;
Date.prototype.GetFromUtcString = System.DateTime.GetFromUtcString;
Date.prototype.DefaultFormat = "yyyy-MM-dd HH:mm:ss";
Date.prototype.ToString = System.DateTime.ToString;


System.Extensions.Apply.apply(this);

 

//==============================================================================
// END
//------------------------------------------------------------------------------