    var Events =
    {
      __cCache : [],
      __cFunctionCache: [],
      __cBodyResizeSet : false,
      __cResizeEventObjects : [],
      __cResizeEventFunctions : [],
      __cResizeFrequencyTimer : 0,
      __cResizeFollowupSet : false,

      add : function(object, eventName, eventFunction)
      {
        if(typeof object == 'string')
        {
          object = document.getElementById(object);
        }
        if(!object)
        {
          return;
        }

        if(eventName)
        {
            if(eventName.toLowerCase() == "resize")
            {
                var ownerDoc    = object.ownerDocument;

                if(!ownerDoc)
                {
                    ownerDoc = document;
                }

                if(object != ownerDoc.body && object != document.body && object != ownerDoc.parentWindow && object != document.parentWindow && object != document.contentWindow && object != document.defaultView && object != window)
                {
                    Events.__addResizeEvent(object, eventFunction);
                    return;
                }
            }
        }

        var id  = object.__eventCacheID;
        var handler;

        if(!id)
        {
          id = Events.__cCache.length;
          for(var i=0,max=Events.__cCache.length;i < max;i++)
          {
            if(Events.__cCache[i] == null)
            {
              id = i;
              break;
            }
          }
          object.__eventCacheID = id;
          Events.__cCache[id] = object;
        }

        // Add and cache the event function.
        var funcId = null;
        // Get the current function identifier.
        if(object.__functionCacheID)
        {
            funcId = object.__functionCacheID[eventName];
        }
        else
        {
            object.__functionCacheID = new Array();
        }
        // If there isn't a function identifier:
        // 1) Create a new identifier.
        // 2) Attach that identifier to the object.
        // 3) Correlate the reference for that identifier to the cached functions to enable retrieval.
        if(!funcId)
        {
            funcId = Events.__cFunctionCache.length;
            for(var i=0,max=Events.__cFunctionCache.length;i < max;i++)
            {
                if(Events.__cFunctionCache[i] == null)
                {
                    funcId = i;
                    break;
                }
            }
            object.__functionCacheID[eventName] = funcId;
            Events.__cFunctionCache[funcId] = new Array();
        }
        Events.__cFunctionCache[funcId][Events.__cFunctionCache[funcId].length] = eventFunction;

        if(!eventFunction.__eventHandlers)
        {
          eventFunction.__eventHandlers = [];
        }

        handler = eventFunction.__eventHandlers[id];

        if(handler)
        {
          if(object.detachEvent)
          {
            object.detachEvent('on'+ eventName, handler);
          }
          object = null;
        }
        else
        {
          object = null;
          handler = function(event)
          {
            return(eventFunction.call(Events.__cCache[id],Events.__setupEvent(event,Events.__cCache[id])));
          };
          eventFunction.__eventHandlers[id] = handler;
        }

        if(Events.__cCache[id].addEventListener)
        {
          Events.__cCache[id].addEventListener(eventName,handler,false);
        }
        else if(Events.__cCache[id].attachEvent)
        {
          Events.__cCache[id].attachEvent('on' + eventName,handler);
        }

        Events.__garbageCollect();
      },

      remove : function(object, eventName, eventFunction)
      {
        if(typeof object == 'string')
        {
          object = document.getElementById(object);
        }
        if(!object)
        {
          return;
        }

        var id              = object.__eventCacheID;
        var handler         = eventFunction;

        // Remove the event function from the object.
        if(Events.__cFunctionCache && object.__functionCacheID)
        {
            var eventFunctions  = Events.__cFunctionCache[object.__functionCacheID[eventName]];

            if(eventFunctions)
            {
                for(var i = 0, maxi = eventFunctions.length; i < maxi; i++)
                {
                    if(eventFunctions[i] && eventFunctions[i] == handler)
                    {
                        eventFunctions[i] = null;
                    }
                }
            }
        }

        // Remove the event handler from the object.
        if(eventFunction.__eventHandlers)
        {
          handler = eventFunction.__eventHandlers[id] || eventFunction;
        }
        if(object.removeEventListener)
        {
          object.removeEventListener(eventName, handler, false);
        }
        else if(object.detachEvent)
        {
          object.detachEvent('on'+ eventName, handler);
          object = null;
        }
        Events.__garbageCollect();
      },

      execute : function(object,eventName)
      {
          var   id      = object.__eventCacheID;
          var   evt     = Events.__createEvent(object,eventName);
          var   ok      = true;
          var   evtFunc = null;

          object.__dl_tmpgetter = function(){return(eval('this.on' + eventName));};
          evtFunc = object.__dl_tmpgetter();
          object.__dl_tmpgetter = null;

          if(evtFunc)
          {
              ok = evtFunc(evt);
              if(!evt.returnValue)
              {
                  ok = false;
              }
          }

          if(ok)
          {
              // Find the events attached to the object.
              if(Events.__cFunctionCache && object.__functionCacheID)
              {
                  var eventFunctions  = Events.__cFunctionCache[object.__functionCacheID[eventName]];

                  if(eventFunctions)
                  {
                      for(var i = 0, maxi = eventFunctions.length; i < maxi && ok; i++)
                      {
                          if(eventFunctions[i])
                          {
                              var   handler = eventFunctions[i].__eventHandlers[id];

                              if(handler)
                              {
                                  ok = handler(evt);
                                  if(!evt.returnValue)
                                  {
                                      ok = false;
                                  }
                              }
                          }
                      }
                  }
              }
          }

          return(ok);
      },

      removeAll : function(object, eventName)
      {
          // Remove the event function from the object.
          if(Events.__cFunctionCache)
          {
              var eventFunctions  = Events.__cFunctionCache[object.__functionCacheID[eventName]];

              for(var i = 0, maxi = eventFunctions.length; i < maxi; i++)
              {
                  if(eventFunctions[i])
                  {
                      Events.remove(object, eventName, eventFunctions[i]);
                  }
              }
          }
      },

      garbageCollect : function()
      {
        for(var i=0,max=Events.__cCache.length;i < max;i++)
        {
          var object  = Events.__cCache[i];

          if(object)
          {
              if(Events._isObjectDeleted(object))
              {
                object.__eventCacheID = null;
                delete Events.__cCache[i];
                Events.__cCache[i] = null;
              }
          }
        }

        if(Events.__cResizeEventObjects)
        {
          for(var i=0,max=Events.__cResizeEventObjects.length;i < max;i++)
          {
            var object  = Events.__cResizeEventObjects[i];

            if(object)
            {
                if(Events._isObjectDeleted(object))
                {
                  delete Events.__cResizeEventObjects[i];
                  Events.__cResizeEventObjects[i] = null;
                  delete Events.__cResizeEventFunctions[i];
                  Events.__cResizeEventFunctions[i] = null;
                }
            }
          }
        }
      },

      _isObjectDeleted : function(object)
      {
          var nodeType = object.nodeType;

          if(!nodeType)
          {
              return(false);
          }
          else if(object == window)
          {
              return(false);
          }
          else if(object == document)
          {
              return(false);
          }
          else if(nodeType == 9)
          {
              return(false);
          }
          else if(nodeType == 11)
          {
              return(true);
          }
          else if(object.parentNode)
          {
              if(nodeType != 1)
              {
                  object = object.parentNode;
              }
              while(object && object.nodeType == 1)
              {
                  object = object.parentNode;
              }

              if(object)
              {
                  return(object.nodeType != 9);
              }
              else
              {
                  return(true);
              }
          }
          else
          {
              return(true);
          }
      },

      __cNextGarbageCollect : 0,

      __garbageCollect : function()
      {
        var now = new Date().getTime();

        if(now > Events.__cNextGarbageCollect)
        {
            Events.__cNextGarbageCollect = now + 1000;
            Events.garbageCollect();
        }
      },

      __setupEvent : function(event,theTarget)
      {
        if(!event)
        {
          event = window.event;
        }

        if(!event.target)
        {
          try { event.target = event.srcElement; } catch(ignored) { }
        }
        if(!event.currentTarget)
        {
          if(theTarget)
          {
            try { event.currentTarget = theTarget; } catch(ignored) { }
          }
          else
          {
            try { event.currentTarget = event.srcElement; } catch(ignored) { }
          }
        }
        if(!event.preventDefault)
        {
          try { event.preventDefault = Events.__eventPreventDefault; } catch(ignored) { }
        }
        if(!event.stopPropagation)
        {
          try { event.stopPropagation = Events.__eventStopPropagation; } catch(ignored) { }
        }
        if(!event.timeStamp)
        {
          try { event.timeStamp = new Date().valueOf(); } catch(ignored) { }
        }
        if(!event.view)
        {
          if(event.srcElement)
          {
            try { event.view = Events.__determineView(event.srcElement); } catch(ignored) { }
          }
          else
          {
            try { event.view = Events.__determineView(window); } catch(ignored) { }
          }
        }
        if(!event.relatedTarget)
        {
          if(/mouseover/i.test(event.type))
          {
            try { event.relatedTarget = event.fromElement; } catch(ignored) { }
          }
          if(/mouseout/i.test(event.type))
          {
            try { event.relatedTarget = event.toElement; } catch(ignored) { }
          }
        }

        return(event);
      },

      __eventPreventDefault : function()
      {
          if(window.event)
          {
            window.event.returnValue = false;
          }
          else
          {
            this.returnValue = false;
          }
      },

      __eventStopPropagation : function()
      {
        if(window.event)
        {
          window.event.cancelBubble = true;
        }
        else
        {
          this.cancelBubble = true;
        }
      },

      __nullFunction : function()
      {
        // no-op
      },

      __createEvent : function(theTarget,theType)
      {
        var event = new Object();

        event.type = theType;
        event.x = 0;
        event.y = 0;
        event.offsetX = 0;
        event.offsetY = 0;
        event.screenX = 0;
        event.screenY = 0;
        event.srcElement = theTarget;
        event.target = theTarget;
        event.currentTarget = theTarget;
        event.preventDefault = Events.__eventPreventDefault;
        event.stopPropagation = Events.__eventStopPropagation;
        event.timeStamp = new Date().valueOf();
        try { event.view = Events.__determineView(theTarget); } catch(ignored) { }
        event.returnValue = true;
        event.cancelBubble = false;

        return(event);
      },

      __determineView : function(onWhat)
      {
        if(onWhat.ownerDocument)
        {
          if(onWhat.ownerDocument.parentWindow)
          {
            return(onWhat.ownerDocument.parentWindow);
          }
        }
        else if(onWhat.parentWindow)
        {
          return(onWhat.parentWindow);
        }
        return(null);
      },

      __addResizeEvent : function(object, eventFunction)
      {
        if(!Events.__cBodyResizeSet)
        {
            var    bod    = null;
            var    win    = null;

            if(object.ownerDocument)
            {
                bod = object.ownerDocument.body;
                if(object.ownerDocument.parentWindow)
                {
                    win = object.ownerDocument.parentWindow;
                }
                else if(object.ownerDocument.contentWindow)
                {
                    win = object.ownerDocument.contentWindow;
                }
                else if(object.ownerDocument.defaultView)
                {
                    try
                    {
                        if(object.ownerDocument.defaultView.constructor)
                        {
                            if(Window)
                            {
                                if(object.ownerDocument.defaultView.constructor == Window)
                                {
                                    win = object.ownerDocument.defaultView;
                                }
                            }
                        }
                    }
                    catch(ignored)
                    {
                        //
                    }
                }
            }
            if(!bod)
            {
                if(document)
                {
                    if(document.body)
                    {
                        bod = document.body;
                    }
                }
            }
            if(!win)
            {
                if(window)
                {
                    win = window;
                }
            }

            if(bod && win)
            {
                Events.add(bod,"resize",Events.__handleBodyResize);
                Events.add(win,"resize",Events.__handleBodyResize);
                Events.__cBodyResizeSet = true;
            }
        }
        object._resizeCacheOldOffsetWidth = object.offsetWidth;
        object._resizeCacheOldOffsetHeight = object.offsetHeight;
        object._resizeCacheOldClientWidth = object.clientWidth;
        object._resizeCacheOldClientHeight = object.clientHeight;

        var idx = Events.__cResizeEventObjects.length;

        Events.__cResizeEventObjects[idx] = object;
        Events.__cResizeEventFunctions[idx] = eventFunction;
      },

      __handleBodyResize : function(event)
      {
        Events.notifyObjectResize(this);
      },

      __resizeFollowup : function()
      {
        var now     = new Date().getTime();
        var diff    = (now - Events.__cResizeFrequencyTimer);

        if(diff >= 500)
        {
            Events.__handleDoingResizes(null);
            Events.__cResizeFollowupSet = false;
        }
        else
        {
            window.setTimeout(Events.__resizeFollowup,600 - diff);
        }
      },

      notifyObjectResize : function(object)
      {
        var now = new Date().getTime();

        if((now - Events.__cResizeFrequencyTimer) > 100)
        {
            Events.__cResizeFrequencyTimer = now;

            if(!Events.__cResizeFollowupSet)
            {
                Events.__cResizeFollowupSet = true;
                window.setTimeout(Events.__resizeFollowup,500);
            }

            Events.__handleDoingResizes(object);
        }
      },

      __handleDoingResizes : function(object)
      {
        for(var i=0,max=Events.__cResizeEventObjects.length;i < max;i++)
        {
            var curObj  = Events.__cResizeEventObjects[i];

            try
            {
                if( curObj._resizeCacheOldOffsetWidth != curObj.offsetWidth ||
                    curObj._resizeCacheOldOffsetHeight != curObj.offsetHeight ||
                    curObj._resizeCacheOldClientWidth != curObj.clientWidth ||
                    curObj._resizeCacheOldClientHeight != curObj.clientHeight   )
                {
                    curObj._resizeCacheOldOffsetWidth = curObj.offsetWidth;
                    curObj._resizeCacheOldOffsetHeight = curObj.offsetHeight;
                    curObj._resizeCacheOldClientWidth = curObj.clientWidth;
                    curObj._resizeCacheOldClientHeight = curObj.clientHeight;
                    Events.__cResizeEventFunctions[i].call(curObj,Events.__createEvent(curObj,'resize'));
                }
            }
            catch(ignored)
            {
                // no-op
            }
        }
      }
    }

