function query4DProjectMethodExecution()
{
	var projectMethod = arguments[0];
	
	var lastArgument = arguments[arguments.length - 1];
	var methodParams = null;
	var callBack = null;
	
	// Check if a callback has been passed as last argument
	if ( typeof lastArgument === "function" )
	{
		callBack = lastArgument;
		methodParams = Array.prototype.slice.call( arguments ).slice( 1, arguments.length - 1 );
	}
	else
	{
		methodParams = Array.prototype.slice.call( arguments ).slice( 1 ); // from element 1 to the end
	}
	
	var requestObject =
	{
		method:		projectMethod,
		parameters:	methodParams
	};

	var request_id = window.JSBridge4D_query(
	{
		request: JSON.stringify( requestObject ),
		persistent: false,
		onSuccess: function( response )
		{
			if ( callBack )
			{
				try
				{
					var parsedObject = JSON.parse( response );
					callBack( parsedObject, null );
				}
				catch ( parseException )
				{
					console.warn( "[4D JS Bridge] Warning, JSON.parse() failed: '" + parseException + "'. Will now try to eval() result." );
					
					try
					{
						var evalObject = eval( response );
						callBack( evalObject, null );
					}
					catch ( evalException )
					{
						console.warn( "[4D JS Bridge] Warning, eval() failed too: '" + evalException + "'." );
						callBack( response, null );
					}
				}
			}
		},
		onFailure: function( error_code, error_message )
		{
			if ( callBack )
				callBack( null, null );
		}
	});

	return requestObject;
}

var proxyHandler =
{
	get:function( target, name, receiver )
	{
		return function()
		{
			var arrayArguments = Array.prototype.slice.call( arguments );

			arrayArguments.unshift( name );

			return query4DProjectMethodExecution.apply( null, arrayArguments );
		};
	}
};

var $4d = new Proxy( {}, proxyHandler );

function defaultBridgeCallBack( result )
{
	var logMessage;
	if ( result != undefined )
	{
		logMessage = "success, result=" + result;
	}
	else
	{
		logMessage = "failure";
	}

	alert( logMessage );
	console.log( logMessage );
}

//$4d.methodProject( "arg1", "arg2", "argN", defaultBridgeCallBack );
