function makeSortby(/* fields ...*/) {
	var aFields = Array.prototype.slice.apply(arguments),
		aNorms = [],
		aFuncs = [];
	for (var i = 0; i < arguments.length; i++) {
		aNorms[i] = 1;
		if ( typeof aFields[i] === 'function' ) {
			aFuncs[i] = aFields[i];
			continue;
		}
		aFuncs[i] = function($,n) { return $[n]; };
		if ( aFields[i].indexOf("!") === 0 ) {
			aNorms[i] = -1;
			aFields[i] = aFields[i].slice(1);
		}
		if ( aFields[i] === 'deprecated' ) {
			aFuncs[i] = function($,n) { return !!$[n]; };
		} else if ( aFields[i] === 'static' ) {
			aFields[i] = 'scope';
			aFuncs[i] = function($,n) { return $[n] === 'static'; };
		} else if ( aFields[i].indexOf("#") === 0 ) {
			aFields[i] = aFields[i].slice(1);
			aFuncs[i] = function($,n) { return $.comment.getTag(n).length > 0; };
		}
	}
	return function(a, b) {
		// info("compare " + a.longname + " : " + b.longname);
		var r = 0,i,va,vb;
		for (i = 0; r === 0 && i < aFields.length; i++) {
			va = aFuncs[i](a,aFields[i]);
			vb = aFuncs[i](b,aFields[i]);
			if ( va && !vb ) {
				r = -aNorms[i];
			} else if ( !va && vb ) {
				r = aNorms[i];
			} else if ( va && vb ) {
				va = String(va).toLowerCase();
				vb = String(vb).toLowerCase();
				if (va < vb) {
					r = -aNorms[i];
				}
				if (va > vb) {
					r = aNorms[i];
				}
			}
			// debug("  " + aFields[i] + ": " + va + " ? " + vb + " = " + r);
		}
		return r;
	};
}
function makeSortby(/* fields ...*/) {
	var aFields = Array.prototype.slice.apply(arguments),
		aNorms = [],
		aFuncs = [];
	for (var i = 0; i < arguments.length; i++) {
		aNorms[i] = 1;
		if ( typeof aFields[i] === 'function' ) {
			aFuncs[i] = aFields[i];
			continue;
		}
		aFuncs[i] = function($,n) { return $[n]; };
		if ( aFields[i].indexOf("!") === 0 ) {
			aNorms[i] = -1;
			aFields[i] = aFields[i].slice(1);
		}
		if ( aFields[i] === 'deprecated' ) {
			aFuncs[i] = function($,n) { return !!$[n]; };
		} else if ( aFields[i] === 'static' ) {
			aFields[i] = 'scope';
			aFuncs[i] = function($,n) { return $[n] === 'static'; };
		} else if ( aFields[i].indexOf("#") === 0 ) {
			aFields[i] = aFields[i].slice(1);
			aFuncs[i] = function($,n) { return $.comment.getTag(n).length > 0; };
		}
	}
	return function(a, b) {
		// info("compare " + a.longname + " : " + b.longname);
		var r = 0,i,va,vb;
		for (i = 0; r === 0 && i < aFields.length; i++) {
			va = aFuncs[i](a,aFields[i]);
			vb = aFuncs[i](b,aFields[i]);
			if ( va && !vb ) {
				r = -aNorms[i];
			} else if ( !va && vb ) {
				r = aNorms[i];
			} else if ( va && vb ) {
				va = String(va).toLowerCase();
				vb = String(vb).toLowerCase();
				if (va < vb) {
					r = -aNorms[i];
				}
				if (va > vb) {
					r = aNorms[i];
				}
			}
			// debug("  " + aFields[i] + ": " + va + " ? " + vb + " = " + r);
		}
		return r;
	};
}
function makeSortby ( /* fields ...*/ ) { var aFields = Array . prototype . slice . apply ( arguments ) , aNorms = [ ] , aFuncs = [ ] ; for ( var i = 0 ; i < arguments . length ; i ++ ) { aNorms [ i ] = 1 ; if ( typeof aFields [ i ] === 'function' ) { aFuncs [ i ] = aFields [ i ] ; continue ; } aFuncs [ i ] = function ( $ , n ) { return $ [ n ] ; } ; if ( aFields [ i ] . indexOf ( "!" ) === 0 ) { aNorms [ i ] = - 1 ; aFields [ i ] = aFields [ i ] . slice ( 1 ) ; } if ( aFields [ i ] === 'deprecated' ) { aFuncs [ i ] = function ( $ , n ) { return ! ! $ [ n ] ; } ; } else if ( aFields [ i ] === 'static' ) { aFields [ i ] = 'scope' ; aFuncs [ i ] = function ( $ , n ) { return $ [ n ] === 'static' ; } ; } else if ( aFields [ i ] . indexOf ( "#" ) === 0 ) { aFields [ i ] = aFields [ i ] . slice ( 1 ) ; aFuncs [ i ] = function ( $ , n ) { return $ . comment . getTag ( n ) . length > 0 ; } ; } } return function ( a , b ) { // info("compare " + a.longname + " : " + b.longname); var r = 0 , i , va , vb ; for ( i = 0 ; r === 0 && i < aFields . length ; i ++ ) { va = aFuncs [ i ] ( a , aFields [ i ] ) ; vb = aFuncs [ i ] ( b , aFields [ i ] ) ; if ( va && ! vb ) { r = - aNorms [ i ] ; } else if ( ! va && vb ) { r = aNorms [ i ] ; } else if ( va && vb ) { va = String ( va ) . toLowerCase ( ) ; vb = String ( vb ) . toLowerCase ( ) ; if ( va < vb ) { r = - aNorms [ i ] ; } if ( va > vb ) { r = aNorms [ i ] ; } } // debug("  " + aFields[i] + ": " + va + " ? " + vb + " = " + r); } return r ; } ; }
/* Make a symbol sorter by some attribute.
/ * Make a symbol sorter by some attribute .
Creates a function that can be used to sort by a list of fields