text: /*global Autolinker */
  /*jshint eqnull:true, boss:true */
  /**
   * @class Autolinker.Util
   * @singleton
   *
   * A few utility methods for Autolinker.
   */
  Autolinker.Util = {
  
  	/**
  	 * @property {Function} abstractMethod
  	 *
  	 * A function object which represents an abstract method.
  	 */
  	abstractMethod : function() { throw "abstract"; },
  
  
  	/**
  	 * @private
  	 * @property {RegExp} trimRegex
  	 *
  	 * The regular expression used to trim the leading and trailing whitespace
  	 * from a string.
  	 */
  	trimRegex : /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  
  
  	/**
  	 * Assigns (shallow copies) the properties of `src` onto `dest`.
  	 *
  	 * @param {Object} dest The destination object.
  	 * @param {Object} src The source object.
  	 * @return {Object} The destination object (`dest`)
  	 */
  	assign : function( dest, src ) {
  		for( var prop in src ) {
  			if( src.hasOwnProperty( prop ) ) {
  				dest[ prop ] = src[ prop ];
  			}
  		}
  
  		return dest;
  	},
  
  
  	/**
  	 * Extends `superclass` to create a new subclass, adding the `protoProps` to the new subclass's prototype.
  	 *
  	 * @param {Function} superclass The constructor function for the superclass.
  	 * @param {Object} protoProps The methods/properties to add to the subclass's prototype. This may contain the
  	 *   special property `constructor`, which will be used as the new subclass's constructor function.
  	 * @return {Function} The new subclass function.
  	 */
  	extend : function( superclass, protoProps ) {
  		var superclassProto = superclass.prototype;
  
  		var F = function() {};
  		F.prototype = superclassProto;
  
  		var subclass;
  		if( protoProps.hasOwnProperty( 'constructor' ) ) {
  			subclass = protoProps.constructor;
  		} else {
  			subclass = function() { superclassProto.constructor.apply( this, arguments ); };
  		}
  
  		var subclassProto = subclass.prototype = new F();  // set up prototype chain
  		subclassProto.constructor = subclass;  // fix constructor property
  		subclassProto.superclass = superclassProto;
  
  		delete protoProps.constructor;  // don't re-assign constructor property to the prototype, since a new function may have been created (`subclass`), which is now already there
  		Autolinker.Util.assign( subclassProto, protoProps );
  
  		return subclass;
  	},
  
  
  	/**
  	 * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the
  	 * end of the string (by default, two periods: '..'). If the `str` length does not exceed
  	 * `len`, the string will be returned unchanged.
  	 *
  	 * @param {String} str The string to truncate and add an ellipsis to.
  	 * @param {Number} truncateLen The length to truncate the string at.
  	 * @param {String} [ellipsisChars=..] The ellipsis character(s) to add to the end of `str`
  	 *   when truncated. Defaults to '..'
  	 */
  	ellipsis : function( str, truncateLen, ellipsisChars ) {
  		if( str.length > truncateLen ) {
  			ellipsisChars = ( ellipsisChars == null ) ? '..' : ellipsisChars;
  			str = str.substring( 0, truncateLen - ellipsisChars.length ) + ellipsisChars;
  		}
  		return str;
  	},
  
  
  	/**
  	 * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below).
  	 *
  	 * @param {Array} arr The array to find an element of.
  	 * @param {*} element The element to find in the array, and return the index of.
  	 * @return {Number} The index of the `element`, or -1 if it was not found.
  	 */
  	indexOf : function( arr, element ) {
  		if( Array.prototype.indexOf ) {
  			return arr.indexOf( element );
  
  		} else {
  			for( var i = 0, len = arr.length; i < len; i++ ) {
  				if( arr[ i ] === element ) return i;
  			}
  			return -1;
  		}
  	},
  
  
  
  	/**
  	 * Performs the functionality of what modern browsers do when `String.prototype.split()` is called
  	 * with a regular expression that contains capturing parenthesis.
  	 *
  	 * For example:
  	 *
  	 *     // Modern browsers:
  	 *     "a,b,c".split( /(,)/ );  // --> [ 'a', ',', 'b', ',', 'c' ]
  	 *
  	 *     // Old IE (including IE8):
  	 *     "a,b,c".split( /(,)/ );  // --> [ 'a', 'b', 'c' ]
  	 *
  	 * This method emulates the functionality of modern browsers for the old IE case.
  	 *
  	 * @param {String} str The string to split.
  	 * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting
  	 *   character(s) will be spliced into the array, as in the "modern browsers" example in the
  	 *   description of this method.
  	 *   Note #1: the supplied regular expression **must** have the 'g' flag specified.
  	 *   Note #2: for simplicity's sake, the regular expression does not need
  	 *   to contain capturing parenthesis - it will be assumed that any match has them.
  	 * @return {String[]} The split array of strings, with the splitting character(s) included.
  	 */
  	splitAndCapture : function( str, splitRegex ) {
  		if( !splitRegex.global ) throw new Error( "`splitRegex` must have the 'g' flag set" );
  
  		var result = [],
  		    lastIdx = 0,
  		    match;
  
  		while( match = splitRegex.exec( str ) ) {
  			result.push( str.substring( lastIdx, match.index ) );
  			result.push( match[ 0 ] );  // push the splitting char(s)
  
  			lastIdx = match.index + match[ 0 ].length;
  		}
  		result.push( str.substring( lastIdx ) );
  
  		return result;
  	},
  
  
  	/**
  	 * Trims the leading and trailing whitespace from a string.
  	 *
  	 * @param {String} str The string to trim.
  	 * @return {String}
  	 */
  	trim : function( str ) {
  		return str.replace( this.trimRegex, '' );
  	}
  
  };