function isArray(testObject) {
    return testObject && !(testObject.propertyIsEnumerable('length')) && typeof testObject === 'object' && typeof testObject.length === 'number';
}


jQuery.tablesorter.addParser({
	// set a unique id
	id: 'numericInput',
	is: function(s) {
		return s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
	},
	format: function(s) {
		var value = s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
        if (value==null) return 0;
		if(isNaN(value[1])) return 0;
		else return value[1]*1;
	},
	// set type, either numeric or text
	type: 'numeric'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'link',
	is: function(s) {
		return s.toLowerCase().match(/<a.+>(\S+)<\/a>/i);
	},
	format: function(s) {
		var value = s.toLowerCase().match(/<a.+>(\S+)<\/a>/i);
		return value[1];
	},
	// set type, either numeric or text
	type: 'text'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'textInput',
	is: function(s) {
		return s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
	},
	format: function(s) {
		var value = s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
		return value[1];
	},
	// set type, either numeric or text
	type: 'text'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'dateInput',
	is: function(s) {
		return s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
	},
	format: function(s) {
		var value = s.toLowerCase().match(/<input.+value=['"](\S+)['"].+type=['"\s]text['"\s]/i);
		if (value==null) value = 0;
		else value = value[1];
		return $.tablesorter.formatFloat(new Date(value).getTime());
	},
	// set type, either numeric or text
	type: 'numeric'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'checkbox',
	is: function(s) {
        return s.toLowerCase().match(/<input.+checked=['"]checked['"]/gi);
    },
	format: function(s) {
        var checked = 0;
        if(s.toLowerCase().match(/<input.+checked=['"]checked['"]/gi)) {
        	checked = 1;
        }
        return checked;
    },
	// set type, either numeric or text
	type: 'numeric'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'textCombobox',
	is: function(s) {
        return s.toLowerCase().match(/<option.+[selected=['"]selected['"]|selected].+>(\S+)<\/option>/gi);
    },
	format: function(s) {
		var value = s.toLowerCase().match(/<option.+[selected=['"]selected['"]|selected].+>(\S+)<\/option>/gi);
		return value[1];
    },
	// set type, either numeric or text
	type: 'text'
});

jQuery.tablesorter.addParser({
	// set a unique id
	id: 'numericCombobox',
	is: function(s) {
        return s.toLowerCase().match(/<option.+[selected=['"]selected['"]|selected].+>([^0-9.,])<\/option>/gi);
    },
	format: function(s) {
		var value = s.toLowerCase().match(/<option.+[selected=['"]selected['"]|selected].+>([^0-9.,])<\/option>/gi);
		if(isNaN(value[1])) return 0;
		else return value[1]*1;
    },
	// set type, either numeric or text
	type: 'numeric'
});
