function exUtils() {

	var app = this;

	/* Quelle für addEvent und removeEvent: http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html */
	app.addEvent = function(obj, type, fn) {
		if (obj.addEventListener)
		{
			obj.addEventListener(type, fn, false);
		}
		else if (obj.attachEvent)
		{
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent("on"+type, obj[type+fn]);
		}
	}

	/* Quelle für addEvent und removeEvent: http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html */
	app.removeEvent = function(obj, type, fn)
	{
		if (obj.removeEventListener)
		{
			obj.removeEventListener(type, fn, false);
		}
		else if (obj.detachEvent)
		{
			obj.detachEvent("on"+type, obj[type+fn]);
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	}

	app.removeClass = function(old, remove)
	{
		var classes;
		var i;
		var f = null;

		if (!old) old = '';
		classes = old.split(' ');
		for (i = 0; i < classes.length; i++)
		{
			if (classes[i] == remove) f = i;
		}
		if (f != null) classes.splice(f, 1);
		return(classes.join(' '));
	}

	app.replaceClass = function(old, toreplace, newclass)
	{
		old = app.removeClass(old, toreplace);
		old = app.addClass(old, newclass);
		return(old);
	}

	app.addClass = function(old, toadd)
	{
		var classes;
		var i;
		var f = null;

		if (!old) old = '';
		classes = old.split(' ');
		for (i = 0; i < classes.length; i++)
		{
			if (classes[i] == toadd) f = i;
		}
		if (f == null) classes.push(toadd);
		return(classes.join(' '));
	}

	app.hasClass = function(classname, classes) {
		var class_strings;
		var i;

		if (!classes) classes = '';
		class_strings = classes.split(' ');
		for (i = 0; i < class_strings.length; i++)
		{
			if (class_strings[i] == classname) return(true);
		}
		return(false);
	}

	app.transform = function(elem, start, stop, step, accel, delay, callback1, callback2) {
		start = (typeof start == 'undefined' || start < 0)? start = 0 : parseInt(start);
		stop = (typeof stop == 'undefined' || stop < 0)? stop = 0 : parseInt(stop);
		step = (typeof step == 'undefined')? step = 10 : step = parseInt(step);
		delay = (typeof delay == 'undefined' || delay < 0)? delay = 50 : parseInt(delay);
		accel = (typeof delay == 'undefined')? accel = 1 : parseInt(accel);

		if (delay < 1) delay = 50;
		if (step == 0) step = 1;
		if (start < stop && step < 0) step = -step;
		else if (stop < start && step > 0) step = -step;

		if (Math.abs(step *accel) > 0.1) {
			step = step *accel;
		} else {
			accel = 1;
		}

		// Blendwert ändern
		if ((step > 0 && start <= stop)
			|| (step < 0 && start >= stop))
		{
			start += step;
			if (step > 0 && start > stop) start = stop;
			if (step < 0 && start < stop) start = stop;
		}

		// Erstes Callback aufrufen
		if (callback1) {
			callback1(elem, start);
		}

		if (start != stop) {
			window.setTimeout(function() { app.transform(elem, start, stop, step, accel, delay, callback1, callback2); } , delay);
		} else if (callback2) {
			callback2(elem);
		}
	}

	app.filterChildNodesRecursive = function(parentNode, nodeName, cName)
	{
		var nodes = new Array();
		var i;
		var dummy;

		if (parentNode)
		{
			if (parentNode.hasChildNodes())
			{
				for (i = 0; i < parentNode.childNodes.length; i++)
				{
					if (parentNode.childNodes[i].nodeType == 1)
					{
						if (!nodeName || parentNode.childNodes[i].nodeName == nodeName)
						{
							if (!cName || app.hasClass(cName, parentNode.childNodes[i].className))
							{
								nodes.push(parentNode.childNodes[i]);
							}
								if (parentNode.childNodes[i].hasChildNodes())
								{
									dummy = app.filterChildNodesRecursive(parentNode.childNodes[i], nodeName, cName);
									nodes = nodes.concat(dummy);
								}
						}
						else
						{
							if (parentNode.childNodes[i].hasChildNodes())
							{
								dummy = app.filterChildNodesRecursive(parentNode.childNodes[i], nodeName, cName);
								nodes = nodes.concat(dummy);
							}
						}
					}
				}
			}
		}
		return(nodes);
	}
}
