if (metrics.length) {
    metrics = {
	lock_count: 2,
	events: metrics,
	/* These could be used to handle cookie-triggered events:
	   events.push((null===m)?'':m[1]);
	   match = /(^|; )s_=([^;]*)/)
	   cookie_reader = setInterval(function() {
	   var match = document.cookie.match(
	   console.log(document.cookie);
	   }, 100);
	*/

	/** Lock the metrics object

	    Data will not be sent to the server while your lock is active
	*/
	lock: function() { ++this.lock_count },
	/** Release a metrics lock

	    Once the last lock on the metrics object is released, the data is sent.

	    The metrics event is guaranteed to still be locked during load time.
	*/
	unlock: function() {
	    //clearInterval(cookie_reader);
	    if (!--this.lock_count) {
		this.events.push("&e=", (new Date()).getTime());
		// Post results
		(new Image()).src=this.events.join('');
		/*
		  console.log(this.events.join('')
		  .replace(/.*?\?r=/, '&Server render period:		')
		  .replace('&h=', '&Hostname:					')
		  .replace('&s=', '&Browser start time:		')
		  .replace('&oReadyStart=', '&Page ready time (start):	')
		  .replace('&oReadyEnd=', '&Page ready time (end):		')
		  .replace('&oLoadStart=', '&Page load time (start):	')
		  .replace('&oLoadEnd=', '&Page load time (end):		')
		  .replace(/&/g, '\n')
		  );
		*/
		this.events = null;
	    }
	},

	/** Checkpoint(event_text)
	    Marks an event as occurring at the time the checkpoint() was called.

	    Note that event names automatically have 'n' prepended to them ('n'on-metircs events),
	    so that they don't clash with metrics event names.

	    Returns the metrics object, so you can do things like:

	    metrics.checkpoint(name).unlock();
	*/
	checkpoint: function(e) {
	    this.events.push('&n', escape(e), '=', (new Date()).getTime());
	    return this;
	},

	ready: function () {
	    metrics.checkpoint("ReadyStart" );
	    setTimeout(function() { metrics.checkpoint("ReadyEnd").unlock() }, 0);
	},

	load: function () {
	    metrics.checkpoint("LoadStart");
	    setTimeout(function() { metrics.checkpoint("LoadEnd").unlock() }, 0);
	},

	_timer_count: 0,

	Timer: function(e) {
	    this.id = [ '&t', (metrics._timer_count++).toString(16), '_' ].join('');

	    metrics.events.push(this.id, escape(e), '=', (new Date()).getTime());

	    metrics.lock();

	    this.checkpoint = function(e) {
		metrics.events.push(this.id, escape(e), '=', (new Date()).getTime());
	    };

	    this.end = function(e) {
		metrics.events.push(this.id, escape(e), '=', (new Date()).getTime());
		metrics.unlock();
	    };
	}

    };

    if ('ready' in $(window)) { // jquery
	$(window)
	    .ready(metrics.ready)
	    .load (metrics.load );
    } else if (document.addEventListener) { // Not IE
        document.addEventListener("DOMContentLoaded", metrics.ready, false);
        window  .addEventListener("load"          , metrics.load , false);
    };
}
