
Array.implement({
	/**
	 * Concatenated additional array items to this array. Not
	 * to be confused with Array.concat(), which flattens array
	 * arguments one extra level before applying the items.
	 * 
	 * @param {arguments} [1..n] arrays whose items are to be
	 *                           concatenated to this array.
	 * @return {Array} the concatenated array.
	 */
	pconcat: function() {
		var newArray = this.clone();
		for(var i = 0; i < arguments.length; i++) {
			for(var j = 0; j < arguments[i].length; j++) {
				newArray.push(arguments[i][j]);
			}
		}
		return newArray;
	}
});

Function.implement({
	/**
	 * this is a modified version of the script described at 
	 * http://dhtmlkitchen.com/?category=/JavaScript/&date=2008/09/11/&entry=Function-prototype-bind
	 * 
	 * Please use this in place of Function.bind() or Function.pass() as
	 * this alleviates issues with partial argument application and
	 * unwanted array argument flattening.
	 * 
	 * @param {Object} context the 'this' value to be used.
	 * @param {arguments} [1..n] optional arguments that are
	 * prepended to returned function's call.
	 * @return {Function} a function that applies the original
	 * function with 'context' as the thisArg.
	 */
	pbind: function(context){
		var fn = this;
		var isPartial = arguments.length > 1;
	  
		var result = function() {};

		// Strategy 1: only one argument, so just bind, not a partialApply
		if(!isPartial) {
			result = function() {
				if(arguments.length !== 0) {
					return fn.apply(context, arguments);
				} else {
					return fn.call(context); // faster in Firefox.
				}
			};
		} else {
			// Strategy 2: partialApply
			var args = Array.prototype.slice.call(arguments, 1);

			result = function() {
				functionArgs = args.pconcat(arguments);
				return fn.apply(context, functionArgs);
			};
		}
		return result;
	}
});

var taipan = {
  console: {
    log: function(foo)
    {
      if (typeof('console') == 'undefined')
        return;
      
      console.log(foo);
    }
  }
};

