/**
 * Mixin that dynamically defines and redefines a filterFeature()
 * method, and supports a filtering hierarchy, and filter chaining at
 * each level of the hierarchy.  Designed to be really fast, because
 * filterFeature() is going to be called many, many times.
 */
define([
           'dojo/_base/declare',
           'dojo/_base/array'
       ],
       function(
           declare,
           array
       ) {
return declare( null, {
    filterFeature: function( feature ) {
        return true;
    },
    addFeatureFilter: function( filter ) {
        var oldFilter = this.filterFeature;
        this.filterFeature = function( feat ) {
            return oldFilter(feat) && filter(feat);
        };
    },
    setFeatureFilter: function( filter ) {
        if( this.featureFilterParentComponent )
            this.filterFeature = function(feat) {
                return filter(feat) && this.featureFilterParentComponent.filterFeature( feat );
            };
        else
            this.filterFeature = filter;
    },
    setFeatureFilterParentComponent: function( parent ) {
        this.featureFilterParentComponent = parent;
        this.setFeatureFilter( this.filterFeature );
    }
});
});
@@ -501,24 +501,55 @@
 rue;%0A    %7D,%0A
+%0A    _featureFilterChain: %5B%5D,%0A%0A
     addFeatu
@@ -591,91 +591,353 @@
     
-var oldFilter = this.filterFeature;%0A        this.filterFeature = function( feat ) %7B
+this._featureFilterChain.push( filter );%0A        this._buildFeatureFilter();%0A    %7D,%0A%0A    removeFeatureFilter: function( filter ) %7B%0A        var newchain = %5B%5D;%0A        for( var i = 0; i %3C this._featureFilterChain.length; i++ ) %7B%0A            if( this._featureFilterChain%5Bi%5D !== filter )%0A                newchain.push( this._featureFilterChain%5Bi%5D );
 %0A   
@@ -945,91 +945,303 @@
     
+%7D%0A
     
-return oldFilter(feat) && filter(feat);%0A        
+    this._featureFilterChain = newchain;%0A        this._buildFeatureFilter();%0A    %7D,%0A%0A    _buildFeatureFilter: function() %7B%0A%0A        // de-dup the filter chain%0A        var filterChain = function() %7B%0A            var seen = %7B
 %7D;%0A    
-%7D,%0A
+    
     
-setFeatureFilter:
+return array.filter( this._featureFilterChain %7C%7C %5B%5D,
  fun
@@ -1245,32 +1245,36 @@
 function( filter
+Func
  ) %7B%0A        if(
@@ -1274,45 +1274,482 @@
     
-if( this.featureFilterParentComponent
+                      var str = filterFunc.toString();%0A                              var s = !( str in seen );%0A                              seen%5Bstr%5D = true;%0A                              return s;%0A                          %7D);%0A        %7D.call(this);%0A%0A        if( ! filterChain.length )%0A            this.filterFeature = function( feat ) %7B%0A                return this.featureFilterParentComponent.filterFeature( feat );%0A            %7D;%0A        else if( filterChain.length == 1
  )%0A 
@@ -1826,17 +1826,35 @@
 n filter
-(
+Chain%5B0%5D.call(this,
 feat) &&
@@ -1977,21 +1977,570 @@
  = f
-ilter;%0A    %7D,
+unction( feat ) %7B%0A                for( var i = 0; i%3CfilterChain.length; i++ )%0A                    if( ! filterChain%5Bi%5D.call( this, feat ) )%0A                        return false;%0A%0A                if( ! this.featureFilterParentComponent.filterFeature( feat ) )%0A                    return false;%0A%0A                return true;%0A            %7D;%0A    %7D,%0A%0A    featureFilterParentComponent: %7B filterFeature: function() %7B return true; %7D %7D,%0A%0A    setFeatureFilter: function( filter ) %7B%0A        this._featureFilterChain = %5B filter %5D;%0A        this._buildFeatureFilter();%0A    %7D,%0A
 %0A   
@@ -2659,19 +2659,22 @@
    this.
-set
+_build
 FeatureF
@@ -2679,36 +2679,16 @@
 eFilter(
- this.filterFeature 
 );%0A    %7D
@@ -2688,15 +2688,16 @@
 ;%0A    %7D%0A
+%0A
 %7D);%0A%7D);

make FeatureFiltererMixin more powerful, add ability to remove individual filters from the filter chain