Function.prototype.closure = function (obj)
{
  // Init object storage.
  if (!window.__objs)
    window.__objs = [];

  // Init closure storage.
  if (!this.__closureFuncs)
    this.__closureFuncs = [];

  // Make sure the object has an id and is stored in the object store.
  var objId = obj.__closureObjId;
  if (!objId)
    __objs[objId = obj.__closureObjId = __objs.length] = obj;

  // See if we previously created a closure for this object/function pair.
  var closureFunc = this.__closureFuncs[objId];
  if (closureFunc)
    return closureFunc;

  // Clear reference to keep the object out of the closure scope.
  obj = null;

  // Create the closure, store in cache and return result.
  var me = this;
  return this.__closureFuncs[objId] = function ()
  {
    return me.apply(__objs[objId], arguments);
  };
};

// Ancient browser compatibility
if (!Function.prototype.apply)
{
  Function.prototype.apply = function (obj, args)
  {
    obj.___fn = this;
    var str = "";
    for (var i = 0; i < args.length; i++)
      str += (i != 0 ? "," : "") + "args[" + i + "]";
    eval("var result = obj.___fn(" + str + ");");
    obj.___fn = null;
    return result;
  };
}