jQuery.fn.nextSibling = function (className)
{
	if (this.length == 0) 
	{ 
		throw "empty nodelist";
		//return this; 
	}
	
	//node - last matched element
	var node = this.get(this.length - 1);
	
	var tmp = className.split('.');
	var tag   = tmp[0];
	className = tmp[1];
	do
	{
	    node = node.nextSibling;
	} while ( node && (
		(className && !$(node).hasClass(className)) ||
		(tag && (node.nodeType == 3 || (node.nodeType == 1 && node.tagName.toLowerCase() != tag) ))
	));

	return jQuery(node);
}

jQuery.fn.previousSibling = function (className)
{
	if (this.length == 0) 
	{ 
		throw "empty nodelist";
		//return this; 
	}
	
	//node - last matched element
	var node = this.get(this.length - 1);
	
	var tmp = className.split('.');
	var tag   = tmp[0];
	className = tmp[1];
	do
	{
	    node = node.previousSibling;
	} while ( node && (
		(className && !$(node).hasClass(className)) ||
		(tag && (node.nodeType == 3 || (node.nodeType == 1 && node.tagName.toLowerCase() != tag) ))
	));

	return jQuery(node);
}

jQuery.fn.parentNode = function(className)
{
	if (this.length == 0) 
	{ 
		throw "empty nodelist";
		//return this; 
	}
	
	//node - last matched element
	var node = this.get(this.length - 1);	
		
	var tmp = className.split('.');
	var tag = tmp[0];
	className = tmp[1];
	
	do {
		node = node.parentNode;
	}
	while (node &&
	((className && !$(node).hasClass(className)) ||
	(tag && (node.nodeType == 3 || (node.nodeType == 1 && node.tagName.toLowerCase() != tag)))));
	
	return jQuery(node);
}
