
	function BRIJ_Error( error_message ) {

		//
		// Properties
		//
		this.error_message = error_message;
		this._Class_name = 'BRIJ_Error';

		//
		// Methods
		//
		this.get_error_message = get_error_message;

		function get_error_message() {
			return this.error_message;
		}

		function get_message() {
			return this.error_message;
		}

	}


	function BRIJ_Request() {


		//
		// Properties
		//
		this.request_method = 'GET';
		this.http_asynchronous = true;
		this.result_handler = null;
		this.result_handler_name = null;
		this.script_filename = null;
		this.request_uri = null;
		this.function_name = null;
		this.parameters = new Array();
		this.class_name = null;
		this.controller = null;
		this.controller_method = null;
		this.param_style = 'key_val';
		
		this._Class_name = 'BRIJ_Request';
		this._Result_handler_params = new Array();
		this._Query_string_vars = new Array();
		this._Request_data;

		//
		// Methods
		//
		this.add_parameter       = add_parameter;
		this.add_result_handler_param = add_result_handler_param;
		this.set_function_name   = set_function_name;
		this.get_function_name	 = get_function_name;
		this.set_script_filename = set_script_filename;
		this.get_script_filename = get_script_filename;
		this.get_request_uri = get_request_uri;
		this.get_function_result = get_function_result;
		this.get_parameters	 = get_parameters;
		this.set_result_handler  = set_result_handler;
		this.get_result_handler  = get_result_handler;
		this.get_result_handler_name  = get_result_handler_name;
		this.set_result_handler_name  = set_result_handler_name;
		this.get_result_handler_params  = get_result_handler_params;
		this.generate_param_string = generate_param_string;
		this.generate_init_string  = generate_init_string;
		this.set_http_asynchronous = set_http_asynchronous;
		this.add_query_string_var = add_query_string_var;
		this.get_query_string_vars = get_query_string_vars;
		this.parse_for_param_string = parse_for_param_string;
		this.set_request_data = set_request_data;
		
		function add_query_string_var( key, val ) {

			this._Query_string_vars[key] = val;

		}

		function get_query_string_vars() {

			return this._Query_string_vars;

		}

		function set_http_asynchronous( val ) {

			this.http_asynchronous = val;

		}
		
		function add_parameter( key, val ) {
			
			if ( typeof(val) == 'undefined' ) {
				//
				// Deprecated call to this method
				//
				this.param_style = 'ordered';
				this.parameters.push(key);
			}
			else {
				this.parameters[key] = val;
			}

		}
	
		function set_function_name( function_name ) {
			this.function_name = function_name;
		}

		function set_script_filename( filename ) {
			this.script_filename = filename;
		}

		function set_request_uri( uri ) {
			
			this.script_filename = uri;
		}

		function get_request_uri() {
			
			try { 
				if ( this.request_uri ) {
					return this.request_uri;
				}
				else {
					return this.script_filename;
				}
			}
			catch(e) {
				throw e;
			}
		}

		function get_script_filename() { //deprecated. Use get_request_uri
			return this.script_filename;
		}

		function get_function_name() {
			return this.function_name;
		}

		function get_parameters() {
			return this.parameters;
		}

		function get_function_result() {

			try { 
				var BRIJ = new FuseBRIJ();
				var result;			

				if ( !this.request_method ) {
					this.request_method = FuseBRIJ.REQUEST_METHOD_GET;
				}
				
				result = BRIJ.get_php_func_result( this );
				
				return result;
			}
			catch(e) {
				throw e;
			}

			

		}

		function set_result_handler( handler ) {
	
			this.result_handler = handler;

		}

		function set_result_handler_name( handler ) {
	
			this.result_handler_name = handler;

		}
		
		function add_result_handler_param( param ) {
				
			this._Result_handler_params.push(param);
		}

		function get_result_handler_params() {
	
			return this._Result_handler_params;

		}

		function get_result_handler_name() {
	
			return this.result_handler_name;

		}

		function get_result_handler() {
	
			return this.result_handler;

		}

		function generate_param_string() {

			try { 
				param_string = '';
		
				var cur_param_val;
				var cur_param_key;

				if ( this.param_style == 'ordered' ) {
					if ( this.parameters ) {
	
						var php = new PHP_Serializer();
	
						for ( j = 0; j < this.parameters.length; j++ ) {

							cur_param_val = php.serialize(this.parameters[j]);
							param_string = param_string + '&param' + eval(j + 1) + '=' + encodeURIComponent(cur_param_val);
						}
					}
				}
				else {
					if ( this._Request_data ) {
						for ( cur_param_key in this._Request_data ) {
							param_string = param_string + this.parse_for_param_string(cur_param_key, this._Request_data[cur_param_key]);  
						}					
					}
					
					for ( cur_param_key in this.parameters ) {
						param_string = param_string + this.parse_for_param_string(cur_param_key, this.parameters[cur_param_key]); //param_string + '&' + cur_param_key + '=' + encodeURIComponent(this.parameters[cur_param_key]); 
					}
					
				}
			
				return param_string;
			}
			catch( e ) {
				throw e;
			}

		}
		
		function set_request_data( data ) {
			
			this._Request_data = data;
			
		}
		
		function parse_for_param_string( key, val, options ) {
			
			try {
				
				var data_string = '';
				var inner_val;
				
				if ( typeof(val) == 'object' ) {
					
					for( inner_val in val ) {
						data_string = data_string + this.parse_for_param_string( inner_val, val[inner_val], { parent_key: key } ); 			
					}
					return data_string;
				}
				
				if ( typeof(options) != 'undefined' ) {
					if ( typeof(options['parent_key']) != 'undefined' ) {
						key = options['parent_key'] + '[' + key + ']';
					}
				}
				
				return key + '=' + encodeURIComponent(val) + '&';
			}
			catch( e ) {
				throw e;
			}
			
		}
		
		function generate_init_string() {

			try {
				
				var init_string = '';
				var qs_key_class_name = FuseBRIJ.QS_KEY_CLASS;
				var qs_key_func_name = FuseBRIJ.QS_KEY_FUNCTION_NAME
				
				if ( this.controller ) {
					this.class_name = this.controller;
					qs_key_class_name = FuseBRIJ.QS_KEY_CONTROLLER;
				}
			
				if ( this.controller_method ) {
					this.function_name = this.controller_method;
					qs_key_func_name = FuseBRIJ.QS_KEY_CONTROLLER_METHOD;
				} 

				
				//if ( !this.function_name ) {
				//	throw 'Missing function or method name in generate_init_string()!';
				//}
			
				if ( this.function_name ) {
		        	init_string = qs_key_func_name + '=' + this.function_name;
				}
		        
		        if ( this.class_name ) {
		        	init_string = init_string + '&' + qs_key_class_name + '=' + this.class_name;
		        }
		        
		        return init_string;
		         
			}
			catch( e ) {
				throw e;
			}
		}

	}


	function FuseBRIJ() {

		var Me = this;
		
		//
		// define properties
		//
		this.request_timeout = 1000; //in ms
		this.script_reference  = null;

		this._Processing_request = false;
		this._Result_function_prefix = '__BRIJ_res_';
		this._Cur_BRIJ_request_obj;
		this._Request_timer = null;
		this._Request_timed_out = false;

		//
		// define methods
		//
		this.get_php_func_result   = get_php_func_result;
		this.set_request_timed_out = set_request_timed_out;
		this.request_timed_out     = request_timed_out;

		//this._Call_result_function = _Call_result_function;
		this._Is_BRIJ_Request_object = _Is_BRIJ_Request_object;
		this._Start_request_timer = _Start_request_timer;
		this._Stop_request_timer = _Stop_request_timer;
		this._Is_timer_running = _Is_timer_running;
		this._Handle_error = _Handle_error;
		this._Raise_error_message = _Raise_error_message;
		this._Get_HTTP_request_object = _Get_HTTP_request_object;
		this._Set_HTTP_request_object = _Set_HTTP_request_object;
		this._Send_HTTP_request = _Send_HTTP_request;
		this._Cancel_HTTP_request = _Cancel_HTTP_request;
		this._Handle_HTTP_response = _Handle_HTTP_response;
		this._Eval_result_function = _Eval_result_function;
		this._Is_HTTP_request_object_busy = _Is_HTTP_request_object_busy;
		this._HTTP_request_obj = null;

		//this._Request_index = 0;
		//this._Increment_request_index = _Increment_request_index;
		//this._Decrement_request_index = _Decrement_request_index;


		__Construct();
		//FuseBRIJ.ACTIVE_OBJECT = this;

		function __Construct() {

			/*
			if ( FuseBRIJ.ACTIVE_OBJECT != null ) {
				if ( http_request_obj = FuseBRIJ.ACTIVE_OBJECT._Get_HTTP_request_object() ) { 
					http_request_obj.abort();
				}
			}
			*/


		}
	
		function _Handle_error( e ) {
			try { 
				this._Raise_error_message( e.message );
			}
			catch (ex) { 
				
			}
		}

		function _Raise_error_message( message ) {

			try {
				if ( FuseBRIJ.DEBUG ) {
					alert( message );
				}
			}
			catch( ex ) {
			}
		}

		/*
		function _Increment_request_index() {
			this._Request_index++;
		}

		function _Decrement_request_index() {
			this._Request_index--;
		}
		*/		

		function get_php_func_result( request_obj ) {

			try {


				var script_filename;
				var function_name;
				var class_name;
				var http_response;
				var params;
				var param_string;

				var j;
				var key;
				var query_string_extras;
				var request_url = null;
				var type_result;

				if ( !this._Is_BRIJ_Request_object(request_obj) ) {
					throw( 'Invalid Request Object' );
				}

				this._Cur_BRIJ_request_obj = request_obj;

				if ( !(script_filename = request_obj.get_request_uri()) ) {
					throw( 'No script filename given' );
				}

				
				request_url = script_filename + '?' + FuseBRIJ.QS_KEY_REQUEST_METHOD + '=' + request_obj.request_method;

				try { 
				    data_string = request_obj.generate_init_string() + '&' + request_obj.generate_param_string();
					
					
					if ( request_obj.request_method == FuseBRIJ.REQUEST_METHOD_GET ) {
				        request_url = request_url + '&' + data_string;
					}
				}
				catch(e) {
					throw e;
				}
			
				query_string_extras = request_obj.get_query_string_vars();

				if ( typeof(query_string_extras) != 'undefined' ) {
					for ( key in query_string_extras ) {
						request_url = request_url + '&' + key + '=' + query_string_extras[key];
					}
				}

				if ( !request_obj.http_asynchronous ) {
					this._Start_request_timer();
				}

				//if ( request_url.length > 140 ) {
				//	document.writeln( request_url );
				//	return;
				//}
				
				if ( FuseBRIJ.DEBUG ) {
					alert( 'Requesting: ' + request_url + "\n" + 'with data string: ' + data_string);
				}
				
				this._Send_HTTP_request(request_url, data_string);

				if ( !request_obj.http_asynchronous ) {
			
					function_result = new BRIJ_Request_status();
					function_result.set_status( FuseBRIJ.BRIJ_REQUEST_STATUS_WAITING )

					while ( !this.request_timed_out() && (is_BRIJ_Request_status(function_result) && function_result.get_status() == FuseBRIJ.BRIJ_REQUEST_STATUS_WAITING) ) { 

						try {
							function_result = this._Handle_HTTP_response();

						}
						catch( response_error ) {
							throw response_error;
						}
					}

					this._Stop_request_timer();

					return function_result;
				}
				
				return true;
			}
			catch (e) {
				throw e;
			}
	
		}
		
		//
		// This function is called statically from the HTTP request object's onreadystatechange 
		// event handler when running in asynchronous mode...
		// 
		function _Handle_HTTP_response( http_request_obj ) {

			try {


				var result_error = false;
				var http_request_obj;
				var response;

				if ( !(http_request_obj = Me._Get_HTTP_request_object()) ) { 
					Me._Raise_error_message( "Couldn't get global HTTP request object." );
					return false;
				}

				if ( http_request_obj.readyState == FuseBRIJ.HTTP_REQUEST_READYSTATE_COMPLETED ) {

					try { 
						Me._Stop_request_timer();
						Me._Processing_request = true;
						if ( (http_request_obj.status == FuseBRIJ.HTTP_REQUEST_STATUS_OK) ) {

							try {
								
								if ( FuseBRIJ.DEBUG ) {
									alert( 'result response' + http_request_obj.responseText );
								}
								
								response = Me._Eval_result_function( http_request_obj.responseText );
								
							}
							catch(e) {
								response = new BRIJ_Error( e.message );
							}
							finally {
								Me._Processing_request = false;
							}	

							if ( Me._Cur_BRIJ_request_obj.http_asynchronous ) {
		
								//	
								// Asynchronous request
								//

								var result_handler_name;
								var result_handler_params;
								var result_handler;
								var param_string = '';
								var j;			

								if ( result_handler = Me._Cur_BRIJ_request_obj.get_result_handler() ) {
									result_handler( response );
								}
								else if ( result_handler_name = Me._Cur_BRIJ_request_obj.get_result_handler_name() ) {
			
									result_handler_params = Me._Cur_BRIJ_request_obj.get_result_handler_params();
									for( j = 0; j < result_handler_params.length; j++ ) {
										param_string = param_string + '\'' + result_handler_params[j] + '\'' + ',';
									}

									if ( param_string.length > 0 ) {
										// Strip trailing comma
										param_string = ',' + param_string.substring(0, param_string.length - 1); 
									}

									try { 
										eval( result_handler_name + '( response' + param_string + ' );' );
									}
									catch (e) {
										Me._Raise_error_message( 'Internal BRIJ error: ' + e.message + ' in _Handle_HTTP_Response' );
										throw e;
									}
								}
								else {
									Me._Raise_error_message( 'BRIJ Error: Couldn\'t find result handler' );
								}
							}
			
							Me._Processing_request = false;
							return response;
						}
					}
					catch(e) { 
						// do nothing...firefox bug here.
					}
					finally { 
						Me._Processing_request = false;
					}
				}
				else {
					//waiting for response
					result = new BRIJ_Request_status();
					result.set_status( FuseBRIJ.BRIJ_REQUEST_STATUS_WAITING )

					return result;

				}

				return true;


			}
			catch(e) {
				Me._Handle_error( e );
				throw e;
			}
			finally {
				Me._Processing_request = false;
			}

		}

		function _Eval_result_function( function_body ) {

			try {

				try { 
					var new_function_obj = new Function(function_body);
					var function_result;				
					function_result = new_function_obj();
				}
				catch ( parse_error ) {
					throw parse_error;
				}

				if ( typeof(function_result) == 'undefined' ) {
					//return false;
					throw 'Error parsing result function';
				}
				else {				
					return function_result;
				}

			}
			catch(e) {
				throw e;
			}

		}	
	

		function _Set_HTTP_request_object() {

			try {
				var http_request;

				if ( typeof(XMLHttpRequest) != 'undefined' ) {
					http_request = new XMLHttpRequest();
				}
				else {

					try {
						http_request = new ActiveXObject('Msxml2.XMLHTTP');
					}
					catch(inner_e) {
						try {
							http_request = new ActiveXObject('Microsoft.XMLHTTP');
						}
						catch(inner_e2) {
							return false;
						}
					}	

				}

				this._HTTP_request_object = http_request;

				return this._HTTP_request_object;
			}
			catch(e) {
				this._Raise_error_message( 'Error in _Set_HTTP_request_object' );
				throw e;
			}

	
		}

		function _Get_HTTP_request_object( which_obj ) {

			try {
				if ( !Me._HTTP_request_object ) {
					this._Set_HTTP_request_object(); //this can still have "this"
				}

				return Me._HTTP_request_object;

			}
			catch (e) {
				Me._Handle_error( e );
			}

		}

		function _Send_HTTP_request( which_url, data ) {

			try {
				var http_request_obj;
				var http_async;

				if ( !(http_request_obj = this._Get_HTTP_request_object()) ) { 
					this._Raise_error_message( "Couldn't get global HTTP request object." );
					return false;
				}

				this.set_request_timed_out(false);

				http_async = this._Cur_BRIJ_request_obj.http_asynchronous;

				if ( http_async ) {
					if ( !this._Cur_BRIJ_request_obj.get_result_handler() && !this._Cur_BRIJ_request_obj.get_result_handler_name() ) {
						throw 'Can\'t use asynchronous HTTP requests without setting a result handler';
					}		
				}


				this._Processing_request = true;


				if ( this._Is_HTTP_request_object_busy(http_request_obj) ) {
					http_request_obj.abort();
				}

				http_request_obj.onreadystatechange = Me._Handle_HTTP_response;
	
				if ( this._Cur_BRIJ_request_obj.request_method == FuseBRIJ.REQUEST_METHOD_GET ) {
			    	http_request_obj.open("GET", which_url, http_async);
        			http_request_obj.send(null);
				}
				else if ( this._Cur_BRIJ_request_obj.request_method == FuseBRIJ.REQUEST_METHOD_POST ) {
      			
      				http_request_obj.open("POST", which_url, http_async);
        			http_request_obj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      				http_request_obj.setRequestHeader("Content-length", data.length);
      				http_request_obj.setRequestHeader("Connection", "close");
			        http_request_obj.send(data);
			    
					
				}
			
			}
			catch(e) {
				this._Raise_error_message( e.message + ' in _Send_HTTP_Request' );
			}
		

		}
	
		function _Is_HTTP_request_object_busy( request_obj ) {

			try {
				switch ( request_obj.readyState ) {
					case 1,2,3:
						return true;
						break;
					default:
						return false;
						break;
				}
			}
			catch(e) {
				this._Raise_error_message( e.message + ' in _Is_HTTP_request_object_busy' );
			}


		}


		function _Start_request_timer() {
			try {
				this._Request_timer = setTimeout( Me._Cancel_HTTP_request, this.request_timeout );
			}
			catch(e) {
				this._Handle_error( e );
			}

		}

		function _Cancel_HTTP_request() {

			try {

				var http_request_obj;
				if ( http_request_obj = Me._Get_HTTP_request_object() ) {
					http_request_obj.onreadystatechange = null;
					http_request_obj.abort();
				}

				Me.set_request_timed_out(true);
			}
			catch(e) {
				Me._Handle_error( e );
			}


		}

		function _Stop_request_timer() {

			try {
				if ( Me._Request_timer ) {
					clearTimeout( Me._Request_timer );
				}
			}
			catch(e) {
				Me._Handle_error( e );
			}

		}

		function request_timed_out() {

			if ( this._Request_timed_out ) {
				return true;
			}

			return 0;

		}

		function set_request_timed_out( tf ) {

			this._Request_timed_out = tf;

		}


		function _Is_timer_running() {

			if ( _BRIJ_WAITING ) {
				return true;
			}

			return false;
		}

		function _Is_BRIJ_Request_object( obj ) {

			try {
				if ( typeof(obj._Class_name) != 'undefined' ) {
					if ( obj._Class_name == 'BRIJ_Request' ) {
						return true;
					}
				}

				return false;
			}
			catch(e) {
				this._Handle_error( e );				
			}

		}

	}

	//
	// End FuseBRIJ class
	//

        function is_BRIJ_Error( obj ) {

                try {
                        if ( typeof(obj) != 'undefined' ) {
                                if ( obj ) {
                                        if ( typeof(obj._Class_name) != 'undefined' ) {
                                                if ( obj._Class_name == 'BRIJ_Error' ) {
                                                        return true;
                                                }
                                        }
                                }
                        }

                        return false;
                }
                catch(e) {
			if ( FuseBRIJ.DEBUG ) {
				alert( e.message );
			}
                }

        }

	function is_BRIJ_Request_status( obj ) {

                try {
                        if ( typeof(obj) != 'undefined' ) {
                                if ( obj ) {
                                        if ( typeof(obj._Class_name) != 'undefined' ) {
                                                if ( obj._Class_name == 'BRIJ_Request_status' ) {
                                                        return true;
                                                }
                                        }
                                }
                        }

                        return 0;
                }
                catch(e) {
			if ( FuseBRIJ.DEBUG ) {
	                        alert( e.message );
			}
                }

	}


	function BRIJ_Request_status() {

		//
		// Properties
		//
		this._Class_name = 'BRIJ_Request_status';
		this._Status = '';

		//
		// Methods
		//
		this.set_status = set_status;
		this.get_status = get_status;

		function set_status( status ) {
			this._Status = status;
		}

		function get_status() {
			return this._Status;
		}
	}

	
	FuseBRIJ.REQUEST_METHOD_GET  = 'GET';
	FuseBRIJ.REQUEST_METHOD_POST = 'POST';

	FuseBRIJ.BRIJ_REQUEST_STATUS_WAITING   = 1;
	FuseBRIJ.BRIJ_REQUEST_STATUS_COMPLETED = 2;

	FuseBRIJ.QS_KEY_FUNCTION_NAME = 'func';
	FuseBRIJ.QS_KEY_CONTROLLER = 'controller';
	FuseBRIJ.QS_KEY_CONTROLLER_METHOD = 'method';
	FuseBRIJ.QS_KEY_CLASS = 'class';
	FuseBRIJ.QS_KEY_REQUEST_METHOD = 'brij_request_method';

	FuseBRIJ.HTTP_REQUEST_READYSTATE_COMPLETED = 4;
	FuseBRIJ.HTTP_REQUEST_STATUS_OK = 200;

	FuseBRIJ.DEBUG = 0;

	function BRIJ_Exception( message ) {

		this.message = message;

		this.get_message = get_message();

		function get_message() {
			return this.message;
		}

	}



/**
 * Object PHP_Serializer
 * 	JavaScript to PHP serialize / unserialize class.
 * This class converts php variables to javascript and vice versa.
 *
 * PARSABLE JAVASCRIPT < === > PHP VARIABLES:
 *	[ JAVASCRIPT TYPE ]		[ PHP TYPE ]
 *	Array		< === > 	array
 *	Object		< === > 	class (*)
 *	String		< === > 	string
 *	Boolean		< === > 	boolean
 *	null		< === > 	null
 *	Number		< === > 	int or double
 *	Date		< === > 	class
 *	Error		< === > 	class
 *	Function	< === > 	class (*)
 *
 * (*) NOTE:
 * Any PHP serialized class requires the native PHP class to be used, then it's not a
 * PHP => JavaScript converter, it's just a usefull serilizer class for each
 * compatible JS and PHP variable types.
 * Lambda, Resources or other dedicated PHP variables are not usefull for JavaScript.
 * There are same restrictions for javascript functions*** too then these will not be sent.
 *
 * *** function test(); alert(php.serialize(test)); will be empty string but
 * *** mytest = new test(); will be sent as test class to php
 * _____________________________________________
 *
 * EXAMPLE:
 *	var php = new PHP_Serializer(); // use new PHP_Serializer(true); to enable UTF8 compatibility
 *	alert(php.unserialize(php.serialize(somevar)));
 *	// should alert the original value of somevar
 * ---------------------------------------------
 * @author              Andrea Giammarchi
 * @site		www.devpro.it
 * @date                2005/11/26
 * @lastmod             2006/05/15 19:00 [modified stringBytes method and removed replace for UTF8 and \r\n]
 * 			[add UTF8 var again, PHP strings if are not encoded with utf8_encode aren't compatible with this object]
 *			[Partially rewrote for a better stability and compatibility with Safari or KDE based browsers]
 *			[UTF-8 now has a native support, strings are converted automatically with ISO or UTF-8 charset]
 *
 * @specialthanks	Fabio Sutto, Kentaromiura, Kroc Camen, Cecile Maigrot, John C.Scott, Matteo Galli
 *
 * @version             2.2, tested on FF 1.0, 1.5, IE 5, 5.5, 6, 7 beta 2, Opera 8.5, Konqueror 3.5, Safari 2.0.3
 */
function PHP_Serializer(UTF8) {
	
	/** public methods */
	function serialize(v) {
		// returns serialized var
		var	s;
		switch(v) {
			case null:
				s = "N;";
				break;
			default:
				s = this[this.__sc2s(v)] ? this[this.__sc2s(v)](v) : this[this.__sc2s(__o)](v);
				break;
		};
		return s;
	};
	
	function unserialize(s) {
		// returns unserialized var from a php serialized string
		__c = 0;
		__s = s;
		return this[__s.substr(__c, 1)]();
	};
	
	function stringBytes(s) {
		// returns the php lenght of a string (chars, not bytes)
		return s.length;
	};
	
	function stringBytesUTF8(s) {
		// returns the php lenght of a string (bytes, not chars)
		var 	c, b = 0,
			l = s.length;
		while(l) {
			c = s.charCodeAt(--l);
			b += (c < 128) ? 1 : ((c < 2048) ? 2 : ((c < 65536) ? 3 : 4));
		};
		return b;
	};
	
	/** private methods */
	function __sc2s(v) {
		return v.constructor.toString();
	};
	
	function __sc2sKonqueror(v) {
		var	f;
		switch(typeof(v)) {
			case ("string" || v instanceof String):
				f = "__sString";
				break;
			case ("number" || v instanceof Number):
				f = "__sNumber";
				break;
			case ("boolean" || v instanceof Boolean):
				f = "__sBoolean";
				break;
			case ("function" || v instanceof Function):
				f = "__sFunction";
				break;
			default:
				f = (v instanceof Array) ? "__sArray" : "__sObject";
				break;
		};
		return f;
	};
	
	function __sNConstructor(c) {
		return (c === "[function]" || c === "(Internal Function)");
	};
	
	function __sCommonAO(v) {
		var	b, n,
			a = 0,
			s = [];
		for(b in v) {
			n = v[b] == null;
			if(n || v[b].constructor != Function) {
				s[a] = [
					(!isNaN(b) && parseInt(b).toString() === b ? this.__sNumber(b) : this.__sString(b)),
					(n ? "N;" : this[this.__sc2s(v[b])] ? this[this.__sc2s(v[b])](v[b]) : this[this.__sc2s(__o)](v[b]))
				].join("");
				++a;
			};
		};
		return [a, s.join("")];
	};
	
	function __sBoolean(v) {
		return ["b:", (v ? "1" : "0"), ";"].join("");
	};
	
	function __sNumber(v) {
		var 	s = v.toString();
		return (s.indexOf(".") < 0 ? ["i:", s, ";"] : ["d:", s, ";"]).join("");
	};
	
	function __sString(v) {
		return ["s:", v.length, ":\"", v, "\";"].join("");
	};
	
	function __sStringUTF8(v) {
		return ["s:", this.stringBytes(v), ":\"", v, "\";"].join("");
	};
	
	function __sArray(v) {
		var 	s = this.__sCommonAO(v);
		return ["a:", s[0], ":{", s[1], "}"].join("");
	};
	
	function __sObject(v) {
		var 	o = this.__sc2s(v),
			n = o.substr(__n, (o.indexOf("(") - __n)),
			s = this.__sCommonAO(v);
		return ["O:", this.stringBytes(n), ":\"", n, "\":", s[0], ":{", s[1], "}"].join("");
	};
	
	function __sObjectIE7(v) {
		var 	o = this.__sc2s(v),
			n = o.substr(__n, (o.indexOf("(") - __n)),
			s = this.__sCommonAO(v);
		if(n.charAt(0) === " ")
			n = n.substring(1);
		return ["O:", this.stringBytes(n), ":\"", n, "\":", s[0], ":{", s[1], "}"].join("");
	};
	
	function __sObjectKonqueror(v) {
		var	o = v.constructor.toString(),
			n = this.__sNConstructor(o) ? "Object" : o.substr(__n, (o.indexOf("(") - __n)),
			s = this.__sCommonAO(v);
		return ["O:", this.stringBytes(n), ":\"", n, "\":", s[0], ":{", s[1], "}"].join("");
	};
	
	function __sFunction(v) {
		return "";
	};
	
	function __uCommonAO(tmp) {
		var	a, k;
		++__c;
		a = __s.indexOf(":", ++__c);
		k = parseInt(__s.substr(__c, (a - __c))) + 1;
		__c = a + 2;
		while(--k)
			tmp[this[__s.substr(__c, 1)]()] = this[__s.substr(__c, 1)]();
		return tmp;
	};

	function __uBoolean() {
		var	b = __s.substr((__c + 2), 1) === "1" ? true : false;
		__c += 4;
		return b;
	};
	
	function __uNumber() {
		var	sli = __s.indexOf(";", (__c + 1)) - 2,
			n = Number(__s.substr((__c + 2), (sli - __c)));
		__c = sli + 3;
		return n;
	};
	
	function __uStringUTF8() {
		var 	c, sls, sli, vls,
			pos = 0;
		__c += 2;
		sls = __s.substr(__c, (__s.indexOf(":", __c) - __c));
		sli = parseInt(sls);
		vls = sls = __c + sls.length + 2;
		while(sli) {
			c = __s.charCodeAt(vls);
			pos += (c < 128) ? 1 : ((c < 2048) ? 2 : ((c < 65536) ? 3 : 4));
			++vls;
			if(pos === sli)
				sli = 0;
		};
		pos = (vls - sls);
		__c = sls + pos + 2;
		return __s.substr(sls, pos);
	};
	
	function __uString() {
		var 	sls, sli;
		__c += 2;
		sls = __s.substr(__c, (__s.indexOf(":", __c) - __c));
		sli = parseInt(sls);
		sls = __c + sls.length + 2;
		__c = sls + sli + 2;
		return __s.substr(sls, sli);
	};
	
	function __uArray() {
		var	a = this.__uCommonAO([]);
		++__c;
		return a;
	};
	
	function __uObject() {
		var 	tmp = ["s", __s.substr(++__c, (__s.indexOf(":", (__c + 3)) - __c))].join(""),
			a = tmp.indexOf("\""),
			l = tmp.length - 2,
			o = tmp.substr((a + 1), (l - a));
		if(eval(["typeof(", o, ") === 'undefined'"].join("")))
			eval(["function ", o, "(){};"].join(""));
		__c += l;
		eval(["tmp = this.__uCommonAO(new ", o, "());"].join(""));
		++__c;
		return tmp;
	};
	
	function __uNull() {
		__c += 2;
		return null;
	};
	
	function __constructorCutLength() {
		function ie7bugCheck(){};
		var	o1 = new ie7bugCheck(),
			o2 = new Object(),
			c1 = __sc2s(o1),
			c2 = __sc2s(o2);
		if(c1.charAt(0) !== c2.charAt(0))
			__ie7 = true;
		return (__ie7 || c2.indexOf("(") !== 16) ? 9 : 10;
	};
	
	/** private variables */
	var 	__c = 0,
		__ie7 = false,
		__b = __sNConstructor(__c.constructor.toString()),
		__n = __b ? 9 : __constructorCutLength(),
		__s = "",
		__a = [],
		__o = {},
		__f = function(){};
	
	/** public prototypes */
	PHP_Serializer.prototype.serialize = serialize;
	PHP_Serializer.prototype.unserialize = unserialize;
	PHP_Serializer.prototype.stringBytes = UTF8 ? stringBytesUTF8 : stringBytes;
	
	/** serialize: private prototypes */
	if(__b) { // Konqueror / Safari prototypes
		PHP_Serializer.prototype.__sc2s = __sc2sKonqueror;
		PHP_Serializer.prototype.__sNConstructor = __sNConstructor;
		PHP_Serializer.prototype.__sCommonAO = __sCommonAO;
		PHP_Serializer.prototype[__sc2sKonqueror(__b)] = __sBoolean;
		PHP_Serializer.prototype.__sNumber = 
		PHP_Serializer.prototype[__sc2sKonqueror(__n)] = __sNumber;
		PHP_Serializer.prototype.__sString = PHP_Serializer.prototype[__sc2sKonqueror(__s)] = UTF8 ? __sStringUTF8 : __sString;
		PHP_Serializer.prototype[__sc2sKonqueror(__a)] = __sArray;
		PHP_Serializer.prototype[__sc2sKonqueror(__o)] = __sObjectKonqueror;
		PHP_Serializer.prototype[__sc2sKonqueror(__f)] = __sFunction;
	}
	else { // FireFox, IE, Opera prototypes
		PHP_Serializer.prototype.__sc2s = __sc2s;
		PHP_Serializer.prototype.__sCommonAO = __sCommonAO;
		PHP_Serializer.prototype[__sc2s(__b)] = __sBoolean;
		PHP_Serializer.prototype.__sNumber = 
		PHP_Serializer.prototype[__sc2s(__n)] = __sNumber;
		PHP_Serializer.prototype.__sString = PHP_Serializer.prototype[__sc2s(__s)] = UTF8 ? __sStringUTF8 : __sString;
		PHP_Serializer.prototype[__sc2s(__a)] = __sArray;
		PHP_Serializer.prototype[__sc2s(__o)] = __ie7 ? __sObjectIE7 : __sObject;
		PHP_Serializer.prototype[__sc2s(__f)] = __sFunction;
	};
	
	/** unserialize: private prototypes */
	PHP_Serializer.prototype.__uCommonAO = __uCommonAO;
	PHP_Serializer.prototype.b = __uBoolean;
	PHP_Serializer.prototype.i =
	PHP_Serializer.prototype.d = __uNumber;
	PHP_Serializer.prototype.s = UTF8 ? __uStringUTF8 : __uString;
	PHP_Serializer.prototype.a = __uArray;
	PHP_Serializer.prototype.O = __uObject;
	PHP_Serializer.prototype.N = __uNull;
};
