(function($) {	

	/* Add the methods to handle constructor & destructor binding to the Namespace class */
	$.concrete.Namespace.addMethods({
		bind_condesc: function(selector, name, func) {
			var ctors = this.store.ctors || (this.store.ctors = $.concrete.RuleList()) ;
			
			var rule;
			for (var i = 0 ; i < ctors.length; i++) {
				if (ctors[i].selector.selector == selector.selector) {
					rule = ctors[i]; break;
				}
			}
			if (!rule) {
				rule = ctors.addRule(selector, 'ctors');
			}
			
			rule[name] = func;
			
			if (!ctors[name+'proxy']) {
				var one = this.one('ctors', name);
				var namespace = this;
				
				var proxy = function(els, i, func) {
					var j = els.length;
					while (j--) {
						var el = els[j];
						
						var tmp_i = el.i, tmp_f = el.f;
						el.i = i; el.f = one;
						try { func.call(namespace.$(el)); }
						catch(e) { el.i = tmp_i; el.f = tmp_f; }					
					}
				}
				
				ctors[name+'proxy'] = proxy;
			}
		}
	});
	
	$.concrete.Namespace.addHandler({
		order: 30,
		
		bind: function(selector, k, v) {
			if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) {
				this.bind_condesc(selector, k, v);
				return true;
			}
		}
	});

	/**
	 * Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate
	 * 
	 * Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that
	 * a series of DOM manipulations will only trigger this once.
	 * 
	 * The downside of this is that things like:
	 *   $('#foo').addClass('tabs'); $('#foo').tabFunctionBar();
	 * won't work.
	 */
	$(document).bind('DOMMaybeChanged', function(){
		// For every namespace
		for (var k in $.concrete.namespaces) {
			// That has constructors or destructors
			var ctors = $.concrete.namespaces[k].store.ctors;
			if (ctors) {
			
				// Keep a record of elements that have matched already
				var matched = $([]), match, add, rem, res, rule, ctor, dtor;
				// Stepping through each selector from most to least specific
				var j = ctors.length;
				while (j--) {
					// Build some quick-acccess variables
				  rule = ctors[j];
					sel = rule.selector.selector;
					ctor = rule.onmatch; 
					dtor = rule.onunmatch;
					// Get the list of elements that match this selector, that haven't yet matched a more specific selector
					res = add = $(sel).not(matched);
					
					// If this selector has a list of elements it matched against last time					
					if (rule.cache) {
						// Find the ones that are extra this time
						add = res.not(rule.cache);
						if (dtor) {
  						// Find the ones that are gone this time
  						rem = rule.cache.not(res);
  						// And call the destructor on them
  						if (rem.length) ctors.onunmatchproxy(rem, j, dtor);
  					}
					}
					
					// Call the constructor on the newly matched ones
					if (add.length && ctor) ctors.onmatchproxy(add, j, ctor);
					
					// Add these matched ones to the list tracking all elements matched so far
					matched = matched.add(res);
					// And remember this list of matching elements again this selector, so next matching we can find the unmatched ones
					ctors[j].cache = res;
				}
			}
		}
	})
	

})(jQuery);

@@ -2137,17 +2137,16 @@
 uick-acc
-c
 ess vari
@@ -2155,18 +2155,17 @@
 les%0A%09%09%09%09
-  
+%09
 rule = c
@@ -2263,16 +2263,22 @@
 nmatch;%0A
+%09%09%09%09%09%0A
 %09%09%09%09%09// 
@@ -2498,21 +2498,16 @@
 ast time
-%09%09%09%09%09
 %0A%09%09%09%09%09if
@@ -2621,18 +2621,17 @@
 dtor) %7B%0A
-  
+%09
 %09%09%09%09%09%09//
@@ -2669,18 +2669,17 @@
 is time%0A
-  
+%09
 %09%09%09%09%09%09re
@@ -2703,18 +2703,17 @@
 t(res);%0A
-  
+%09
 %09%09%09%09%09%09//
@@ -2745,18 +2745,17 @@
 on them%0A
-  
+%09
 %09%09%09%09%09%09if
@@ -2804,18 +2804,17 @@
  dtor);%0A
-  
+%09
 %09%09%09%09%09%7D%0A%09

Fix some whitespace issues in jquery.concrete.ctors.js