//memory-leaks sanitizing code
if (!window.RichFaces) {
	window.RichFaces = {};
}

if (!window.RichFaces.Memory) {
	window.RichFaces.Memory = {

		cleaners: {},
		
		addCleaner: function (name, cleaner) {
			this.cleaners[name] = cleaner;
		},

		applyCleaners: function (node, isAjax) {
			for (var name in this.cleaners) {
				this.cleaners[name](node, isAjax);
			}
		},
		
		clean: function (oldNode, isAjax) {
		    if (oldNode) {
		    	this.applyCleaners(oldNode, isAjax);
			
				//node.all is quicker than recursive traversing
			    //window doesn't have "all" attribute
			    var all = oldNode.all;
			    
			    if (all) {
			        var counter = 0;
			        var length = all.length;
			        
			        for (var counter = 0; counter < length; counter++ ) {
				    	this.applyCleaners(all[counter], isAjax);
			        }
			    } else {
			    	var node = oldNode.firstChild;
			    	while (node) {
			    		this.clean(node, isAjax);
			        	node = node.nextSibling;
			    	}
			    }
		    }
		}
	};
	
	window.RichFaces.Memory.addCleaner("richfaces", function(node, isAjax) {
		var component = node.component;
		if (component) {
			var destructorName = component["rich:destructor"];
			//destructor name is required to be back-compatible
			if (destructorName) {
				var destructor = component[destructorName];
				if (destructor) {
					destructor.call(component, isAjax);
				}
			}
		}
	});
	
	if (window.attachEvent) {
	    window.attachEvent("onunload", function() {
	    	var memory = window.RichFaces.Memory;
	    	memory.clean(document);
	    	memory.clean(window);
	    });
	}
}

//