diff --git a/modules/Bio/EnsEMBL/IdMapping/Cache.pm b/modules/Bio/EnsEMBL/IdMapping/Cache.pm
index d67ec2b04235801863f40f10ce1793600a09bff8..a6768f1171cdb4cba12b38c06a575815c005b263 100644
--- a/modules/Bio/EnsEMBL/IdMapping/Cache.pm
+++ b/modules/Bio/EnsEMBL/IdMapping/Cache.pm
@@ -404,8 +404,21 @@ sub build_cache_from_genes {
 
   Arg[1]      : Listref of Bio::EnsEMBL::Genes $genes - the genes to filter
   Example     : my @filtered = @{ $cache->filter_biotypes(\@genes) };
-  Description : Filters a list of genes by biotype. Biotypes are taken from the
-                IdMapping configuration parameter 'biotypes'.
+
+  Description : Filters a list of genes by biotype.  Biotypes are
+                taken from the IdMapping configuration parameter
+                'biotypes' or 'not_biotypes'.
+
+                If the configuration parameter 'not_biotypes' is
+                defined, then rather than returning the genes whose
+                biotype is listed in the configuration parameter
+                'biotypes' the method will return the genes whose
+                biotype is *not* listed in the 'not_biotypes'
+                configuration parameter.
+
+                It is an error to define both these configuration
+                parameters.
+
   Return type : Listref of Bio::EnsEMBL::Genes (or empty list)
   Exceptions  : none
   Caller      : internal
@@ -415,17 +428,50 @@ sub build_cache_from_genes {
 =cut
 
 sub filter_biotypes {
-  my $self = shift;
-  my $genes = shift;
+  my ( $self, $genes ) = @_;
 
-  my $filtered = [];
+  my @filtered;
+  my @biotypes;
+  my $opt_reverse;
 
-  foreach my $biotype ($self->conf->param('biotypes')) {
-    push @$filtered, grep { $_->biotype eq $biotype } @$genes;
+  if ( defined( $self->conf()->param('biotypes') ) ) {
+    if ( defined( $self->conf()->param('not_biotypes') ) ) {
+      $self->logger()
+        ->error( "You may not use both 'biotypes' and 'not_biotypes' " .
+                 "in the configuration" );
+    }
+
+    @biotypes    = $self->conf()->param('biotypes');
+    $opt_reverse = 0;
+  }
+  else {
+    @biotypes    = $self->conf()->param('not_biotypes');
+    $opt_reverse = 1;
   }
 
-  return $filtered;
-}
+  foreach my $gene ( @{$genes} ) {
+    my $keep_gene;
+
+    foreach my $biotype (@biotypes) {
+      if ( $gene->biotype() eq $biotype ) {
+        if   ($opt_reverse) { $keep_gene = 0 }
+        else                { $keep_gene = 1 }
+        last;
+      }
+    }
+
+    if ( defined($keep_gene) ) {
+      if ($keep_gene) {
+        push( @filtered, $gene );
+      }
+    }
+    elsif ($opt_reverse) {
+      push( @filtered, $gene );
+    }
+  }
+
+  return \@filtered;
+} ## end sub filter_biotypes
 
 
 =head2 add