diff --git a/modules/Bio/EnsEMBL/Hive/AnalysisCtrlRule.pm b/modules/Bio/EnsEMBL/Hive/AnalysisCtrlRule.pm
index 1711004bbece71876ae5f9f507d07653398ba0bf..48c2c282483367d59e4d4ecede0d1d0ad9484d90 100755
--- a/modules/Bio/EnsEMBL/Hive/AnalysisCtrlRule.pm
+++ b/modules/Bio/EnsEMBL/Hive/AnalysisCtrlRule.pm
@@ -58,10 +58,21 @@ use Bio::EnsEMBL::Utils::Exception;
 =cut
 
 sub new {
-  my ($class,@args) = @_;
-  my $self = bless {}, $class;
+    my $class   = shift @_;
+    my $self    = bless {}, $class;
   
-  return $self;
+    my ( $dbID, $adaptor, $condition_analysis_url, $ctrled_analysis_id ) =
+    rearrange( [ qw (DBID ADAPTOR CONDITION_ANALYSIS_URL CTRLED_ANALYSIS_ID) ], @_ );
+
+        # database persistence:
+    $self->dbID( $dbID )                            if(defined($dbID));
+    $self->adaptor( $adaptor )                      if(defined($adaptor));
+
+        # simple scalars:
+    $self->condition_analysis_url( $condition_analysis_url )    if(defined($condition_analysis_url));
+    $self->ctrled_analysis_id( $ctrled_analysis_id )            if(defined($ctrled_analysis_id));
+
+    return $self;
 }
 
 sub adaptor {
diff --git a/modules/Bio/EnsEMBL/Hive/AnalysisJob.pm b/modules/Bio/EnsEMBL/Hive/AnalysisJob.pm
index 265e9df336eabb752322ee42d99dc11b4a3c724a..5d25998ef58a8f8658c7c42d5f819e3d7cadf71c 100755
--- a/modules/Bio/EnsEMBL/Hive/AnalysisJob.pm
+++ b/modules/Bio/EnsEMBL/Hive/AnalysisJob.pm
@@ -263,7 +263,7 @@ sub dataflow_output_id {
 
         if($target_analysis_or_table->can('dataflow')) {
 
-            my $insert_ids = $target_analysis_or_table->dataflow( $output_ids_for_this_rule );
+            $target_analysis_or_table->dataflow( $output_ids_for_this_rule );
 
         } else {
 
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/AnalysisCtrlRuleAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/AnalysisCtrlRuleAdaptor.pm
index 33b6f23bd8e562fe551871902e3f5381c00ac6f5..3d443c096d49f82fdc13643eb8c47b399c41d825 100755
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/AnalysisCtrlRuleAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/AnalysisCtrlRuleAdaptor.pm
@@ -1,12 +1,3 @@
-# Perl module for Bio::EnsEMBL::Hive::DBSQL::AnalysisCtrlRuleAdaptor
-#
-# Date of creation: 22.03.2004
-# Original Creator : Jessica Severin <jessica@ebi.ac.uk>
-#
-# Copyright EMBL-EBI 2004
-#
-# You may distribute this module under the same terms as perl itself
-
 =pod
 
 =head1 NAME
@@ -15,8 +6,8 @@
 
 =head1 SYNOPSIS
 
-  $AnalysisCtrlRuleAdaptor = $db_adaptor->get_AnalysisCtrlRuleAdaptor;
-  $analysisCtrlRuleAdaptor = $analysisCtrlRuleObj->adaptor;
+  $analysis_ctrl_rule_adaptor = $db_adaptor->get_AnalysisCtrlRuleAdaptor;
+  $analysis_ctrl_rule_adaptor = $analysisCtrlRuleObj->adaptor;
 
 =head1 DESCRIPTION
 
@@ -27,98 +18,32 @@
 
   Please contact ehive-users@ebi.ac.uk mailing list with questions/suggestions.
 
-=head1 APPENDIX
-
-  The rest of the documentation details each of the object methods.
-  Internal methods are usually preceded with a _
-  
 =cut
 
 
-
 package Bio::EnsEMBL::Hive::DBSQL::AnalysisCtrlRuleAdaptor;
 
 use strict;
-use Carp;
 use Bio::EnsEMBL::Hive::AnalysisCtrlRule;
-use Bio::EnsEMBL::Utils::Argument;
-use Bio::EnsEMBL::Utils::Exception;
-
-use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
-
-
-=head2 fetch_all_by_ctrled_analysis_id
-
-  Arg [1]    : int $id
-               the unique database identifier for the feature to be obtained
-  Example    : $ctrlRuleArray = $adaptor->fetch_all_by_ctrled_analysis_id($ctrled_analysis->dbID);
-  Description: Returns an array reference of all the AnalysisCtrlRule objects 
-               for the specified controled analysis.
-  Returntype : listref of Bio::EnsEMBL::Hive::AnalysisCtrlRule objects
-  Exceptions : thrown if $id is not defined
-  Caller     : general
-  
-=cut
-
-sub fetch_all_by_ctrled_analysis_id {
-  my ($self,$id) = @_;
 
-  unless(defined $id) {
-    throw("fetch_all_by_ctrled_analysis_id must have an id");
-  }
+use base ('Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor');
 
-  my $constraint = "r.ctrled_analysis_id = $id";
 
-  return $self->_generic_fetch($constraint);
+sub default_table_name {
+    return 'analysis_ctrl_rule';
 }
 
 
-=head2 fetch_all
-
-  Arg        : None
-  Example    : my $all_rules = $ctrlRuleDBA->fetch_all();
-  Description: fetches all AnalysisCtrlRule objects from database
-  Returntype : array reference of Bio::EnsEMBL::Hive::AnalysisCtrlRule objects
-  Exceptions : none
-  Caller     : general
-  
-=cut
-
-sub fetch_all {
-  my $self = shift;
-  return $self->_generic_fetch();
+sub default_insertion_method {
+    return 'INSERT_IGNORE';
 }
 
-=head2 store
-
-  Arg[1]     : Bio::EnsEMBL::Hive::AnalysisCtrlRule object
-  Usage      : $self->store( $rule );
-  Function   : Stores a rule in db
-               Sets adaptor and dbID in AnalysisCtrlRule object
-  Returntype : none
 
-=cut
-
-sub store {
-    my ( $self, $rule ) = @_;
-
-    my $newly_inserted_rule = 0;
-
-    my $condition_analysis_url = $rule->condition_analysis_url;
-    my $ctrled_analysis_id     = $rule->ctrled_analysis_id;
+sub object_class {
+    return 'Bio::EnsEMBL::Hive::AnalysisCtrlRule';
+}
 
-    my $sth = $self->prepare("INSERT IGNORE INTO analysis_ctrl_rule (condition_analysis_url, ctrled_analysis_id) VALUES(?,?)");
 
-    my $rtnCode = $sth->execute($condition_analysis_url, $ctrled_analysis_id);
-    if($rtnCode and ($rtnCode != 0E0)) {    # 0E0 is returned when the command succeeds, but 0 rows are updated (so in case of 'INSERT IGNORE' likely a key clash)
-        $newly_inserted_rule = 1;
-        $sth->finish();
-    } elsif(!$rtnCode) {
-        die "Could not create analysis_ctrl_rule('$condition_analysis_url', '$ctrled_analysis_id')";
-    }
-    $rule->adaptor( $self );
-    return $newly_inserted_rule;
-}
 
 
 =head2 remove_by_condition_analysis_url
@@ -156,11 +81,10 @@ sub remove_by_condition_analysis_url {
                 analysis will only unblock if ALL conditions are satisified.
   Returntype  : none
   Exceptions  : none
-  Caller      : general
+  Caller      : HiveGeneric_conf.pm and various pipeline-creating scripts
   
 =cut
 
-
 sub create_rule {
     my ($self, $conditionAnalysis, $ctrledAnalysis) = @_;
 
@@ -171,121 +95,8 @@ sub create_rule {
     $rule->ctrled_analysis($ctrledAnalysis);
     $rule->condition_analysis($conditionAnalysis);
 
-    return $self->store($rule);
-}
-
-############################
-#
-# INTERNAL METHODS
-# (pseudo subclass methods)
-#
-############################
-
-#internal method used in multiple calls above to build objects from table data
-
-sub _tables {
-  my $self = shift;
-
-  return (['analysis_ctrl_rule', 'r']);
-}
-
-
-sub _columns {
-  my $self = shift;
-
-  return qw (r.ctrled_analysis_id
-             r.condition_analysis_url
-            );
-}
-
-
-sub _objs_from_sth {
-  my ($self, $sth) = @_;
-  my @rules = ();
-
-  my ($ctrled_analysis_id, $condition_analysis_url);
-  $sth->bind_columns(\$ctrled_analysis_id, \$condition_analysis_url);
-
-  while ($sth->fetch()) {
-    my $rule = Bio::EnsEMBL::Hive::AnalysisCtrlRule->new;
-    $rule->adaptor($self);
-    $rule->ctrled_analysis_id($ctrled_analysis_id);
-    $rule->condition_analysis_url($condition_analysis_url);
-    push @rules, $rule;
-  }
-  return \@rules;
+    return $self->store($rule, 1);  # avoid redundancy
 }
 
 
-sub _default_where_clause {
-  my $self = shift;
-  return '';
-}
-
-
-sub _final_clause {
-  my $self = shift;
-  return '';
-}
-
-###############################################################################
-#
-# General access methods that could be moved
-# into a superclass
-#
-###############################################################################
-
-sub _generic_fetch {
-  my ($self, $constraint, $join) = @_;
-
-  my @tables = $self->_tables;
-  my $columns = join(', ', $self->_columns());
-
-  if ($join) {
-    foreach my $single_join (@{$join}) {
-      my ($tablename, $condition, $extra_columns) = @{$single_join};
-      if ($tablename && $condition) {
-        push @tables, $tablename;
-
-        if($constraint) {
-          $constraint .= " AND $condition";
-        } else {
-          $constraint = " $condition";
-        }
-      }
-      if ($extra_columns) {
-        $columns .= ", " . join(', ', @{$extra_columns});
-      }
-    }
-  }
-
-  #construct a nice table string like 'table1 t1, table2 t2'
-  my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
-
-  my $sql = "SELECT $columns FROM $tablenames";
-
-  my $default_where = $self->_default_where_clause;
-  my $final_clause = $self->_final_clause;
-
-  #append a where clause if it was defined
-  if($constraint) {
-    $sql .= " WHERE $constraint ";
-    if($default_where) {
-      $sql .= " AND $default_where ";
-    }
-  } elsif($default_where) {
-    $sql .= " WHERE $default_where ";
-  }
-
-  #append additional clauses which may have been defined
-  $sql .= " $final_clause";
-
-  my $sth = $self->prepare($sql);
-  $sth->execute;
-
-#  print STDERR $sql,"\n";
-
-  return $self->_objs_from_sth($sth);
-}
-
 1;
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/BaseAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/BaseAdaptor.pm
new file mode 100644
index 0000000000000000000000000000000000000000..9d859ce7633843ef42e27e052fbf259dad58395d
--- /dev/null
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/BaseAdaptor.pm
@@ -0,0 +1,405 @@
+package Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor;
+
+use strict;
+use Data::Dumper;
+no strict 'refs';   # needed to allow AUTOLOAD create new methods
+
+use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
+
+
+sub default_table_name {
+    die "Please define table_name either by setting it via table_name() method or by redefining default_table_name() in your adaptor class";
+}
+
+
+sub default_insertion_method {
+    return 'INSERT_IGNORE';
+}
+
+
+sub table_name {
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_table_name} = shift @_;
+    }
+    return $self->{_table_name} || $self->default_table_name();
+}
+
+
+sub insertion_method {
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_insertion_method} = shift @_;
+    }
+    return $self->{_insertion_method} || $self->default_insertion_method();
+}
+
+
+sub object_class {      # this one can stay undefined
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_object_class} = shift @_;
+    }
+    return $self->{_object_class};
+}
+
+
+sub column_set {
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_column_set} = shift @_;
+    } elsif( !defined( $self->{_column_set} ) ) {
+        $self->_table_info_loader();
+    }
+    return $self->{_column_set};
+}
+
+
+sub primary_key {        # not necessarily auto-incrementing
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_primary_key} = shift @_;
+    } elsif( !defined( $self->{_primary_key} ) ) {
+        $self->_table_info_loader();
+    }
+    return $self->{_primary_key};
+}
+
+
+sub updatable_column_list {    # it's just a cashed view, you cannot set it directly
+    my $self = shift @_;
+
+    unless($self->{_updatable_column_list}) {
+        my %primary_key_set = map { $_ => 1 } @{$self->primary_key()};
+        my $column_set      = $self->column_set();
+        $self->{_updatable_column_list} = [ grep { not $primary_key_set{$_} } keys %$column_set ];
+    }
+    return $self->{_updatable_column_list};
+}
+
+
+sub autoinc_id {
+    my $self = shift @_;
+
+    if(@_) {    # setter
+        $self->{_autoinc_id} = shift @_;
+    } elsif( !defined( $self->{_autoinc_id} ) ) {
+        $self->_table_info_loader();
+    }
+    return $self->{_autoinc_id};
+}
+
+
+sub _table_info_loader {
+    my $self = shift @_;
+
+    my $dbc         = $self->dbc();
+    my $dbname      = $dbc->dbname();
+    my $table_name  = $self->table_name();
+
+    my %column_set  = ();
+    my @primary_key = ();
+    my $autoinc_id  = '';
+
+    my $sql = "SELECT column_name,column_key,extra FROM information_schema.columns WHERE table_schema='$dbname' and table_name='$table_name'";
+    my $sth = $self->prepare($sql);
+    $sth->execute;  
+    while(my ($column_name, $column_key, $extra) = $sth->fetchrow ) {
+        $column_set{$column_name} = 1;
+        if($column_key eq 'PRI') {
+            push @primary_key, $column_name;
+            if($extra eq 'auto_increment') {
+                $autoinc_id = $column_name;
+            }
+        }
+    }
+    $sth->finish;
+
+    $self->column_set(  \%column_set );
+    $self->primary_key( \@primary_key );
+    $self->autoinc_id(   $autoinc_id );
+}
+
+
+sub count_all {
+    my ($self, $constraint) = @_;
+
+    my $table_name      = $self->table_name();
+
+    my $sql = "SELECT COUNT(*) FROM $table_name";
+
+    if($constraint) { 
+        $sql .= " WHERE $constraint ";
+    }
+
+    print STDOUT $sql,"\n";
+
+    my $sth = $self->prepare($sql);
+    $sth->execute;  
+    my ($count) = $sth->fetchrow();
+    $sth->finish;  
+
+    return $count;
+}
+
+
+sub fetch_all {
+    my ($self, $constraint) = @_;
+
+    my $table_name      = $self->table_name();
+    my $columns_csv     = join(', ', keys %{$self->column_set()});
+    my $object_class    = $self->object_class();
+
+    my $sql = "SELECT $columns_csv FROM $table_name";
+
+    if($constraint) { 
+        $sql .= " WHERE $constraint ";
+    }
+
+    # print STDOUT $sql,"\n";
+
+    my $sth = $self->prepare($sql);
+    $sth->execute;  
+
+    my @objects;
+
+    while(my $hashref = $sth->fetchrow_hashref) {
+        if($object_class) {
+            push @objects, $object_class->new( -adaptor => $self, map { ('-'.uc($_) => $hashref->{$_}) } keys %$hashref );
+        } else {
+            push @objects, $hashref;                            # faster, but only works for naked data types and lacks a link back to the adaptor
+        }
+    }
+    $sth->finish;  
+
+    return \@objects;
+}
+
+
+sub primary_key_constraint {
+    my $self = shift @_;
+
+    my $primary_key  = $self->primary_key();  # Attention: the order of primary_key columns of your call should match the order in the table definition!
+
+    if(@$primary_key) {
+        return join (' AND ', map { $primary_key->[$_]."='".$_[$_]."'" } (0..scalar(@$primary_key)-1));
+    } else {
+        my $table_name = $self->table_name();
+        die "Table '$table_name' doesn't have a primary_key";
+    }
+}
+
+
+sub fetch_by_dbID {
+    my $self = shift @_;    # the rest in @_ should be primary_key column values
+
+    return $self->fetch_all( $self->primary_key_constraint( @_ ) );
+}
+
+
+sub slicer {    # take a slice of the object (if only we could inline in Perl!)
+    my ($self, $object, $fields) = @_;
+
+    if( my $object_class = $self->object_class() ) {
+        return [ map { $object->$_() } @$fields ];
+    } else {
+        return [ @$object{@$fields} ];  # <--- slicing a hashref here
+    }
+    
+}
+
+
+sub remove {    # remove the object by primary_key
+    my $self    = shift @_;
+    my $object  = shift @_;
+
+    my $table_name              = $self->table_name();
+    my $primary_key_constraint  = $self->primary_key_constraint( $self->slicer($object, $self->primary_key()) );
+
+    my $sql = "DELETE FROM $table_name WHERE $primary_key_constraint";
+    my $sth = $self->prepare($sql);
+    $sth->execute();
+    $sth->finish();
+}
+
+
+sub update {    # update (some or all) non_primary columns from the primary
+    my $self    = shift @_;
+    my $object  = shift @_;    # the rest in @_ should be the column names to be updated
+
+    my $table_name              = $self->table_name();
+    my $primary_key_constraint  = $self->primary_key_constraint( $self->slicer($object, $self->primary_key()) );
+    my $columns_to_update       = scalar(@_) ? \@_ : $self->updatable_column_list();
+    my $values_to_update        = $self->slicer( $object, $columns_to_update );
+
+    unless(@$columns_to_update) {
+        die "There are no dependent columns to update, as everything seems to belong to the primary key";
+    }
+
+    my $sql = "UPDATE $table_name SET ".join(', ', map { "$columns_to_update->[$_]=$values_to_update->[$_]" } (0..@$columns_to_update-1) )." WHERE $primary_key_constraint";
+    my $sth = $self->prepare($sql);
+    $sth->execute();
+    $sth->finish();
+}
+
+
+sub check_object_present_in_db {    # return autoinc_id/undef if the table has autoinc_id or just 1/undef if not
+    my ( $self, $object ) = @_;
+
+    my $table_name  = $self->table_name();
+    my $column_set  = $self->column_set();
+    my $autoinc_id  = $self->autoinc_id();
+
+    my $non_autoinc_columns = [ grep { $_ ne $autoinc_id } keys %$column_set ];
+    my $non_autoinc_values  = $self->slicer( $object, $non_autoinc_columns );
+
+    my $sql = 'SELECT '.($autoinc_id or 1)." FROM $table_name WHERE ".
+            # we look for identical contents, so must skip the autoinc_id columns when fetching:
+        join(' AND ', map { my $v=$non_autoinc_values->[$_]; "$non_autoinc_columns->[$_] ".(defined($v) ? "='$v'" : 'IS NULL') } (0..@$non_autoinc_columns-1) );
+
+    my $sth = $self->prepare($sql);
+    $sth->execute();
+
+    my ($return_value) = $sth->fetchrow();
+    $sth->finish;
+
+    return $return_value;
+}
+
+
+sub store {
+    my ($self, $object_or_list, $check_presence_in_db_first) = @_;
+
+    my $objects = (ref($object_or_list) eq 'ARRAY')     # ensure we get an array of objects to store
+        ? $object_or_list
+        : [ $object_or_list ];
+    return unless(scalar(@$objects));
+
+    my $table_name          = $self->table_name();
+    my $column_set          = $self->column_set();
+    my $autoinc_id          = $self->autoinc_id();
+    my $insertion_method    = $self->insertion_method;  # INSERT, INSERT_IGNORE or REPLACE
+    $insertion_method       =~ s/_/ /g;
+
+    my $object_class        = $self->object_class();
+
+        # NB: here we assume all hashes will have the same keys:
+    my $non_autoinc_columns = [ grep { $_ ne $autoinc_id } keys %$column_set ];
+
+        # By using question marks we can insert true NULLs by setting corresponding values to undefs:
+    my $sql = "$insertion_method INTO $table_name (".join(', ', @$non_autoinc_columns).') VALUES ('.join(',', (('?') x scalar(@$non_autoinc_columns))).')';
+    my $sth;    # do not prepare the statement until there is a real need
+
+    foreach my $object (@$objects) {
+        if($check_presence_in_db_first and my $present = $self->check_object_present_in_db($object)) {
+            if($autoinc_id) {
+                if($object_class) {
+                    $object->dbID($present);
+                } else {
+                    $object->{$autoinc_id} = $present;
+                }
+            }
+        } else {
+            $sth ||= $self->prepare( $sql );    # only prepare (once) if we get here
+
+            my $non_autoinc_values = $self->slicer( $object, $non_autoinc_columns );
+
+            my $return_code = $sth->execute( @$non_autoinc_values )
+                    # using $return_code in boolean context allows to skip the value '0E0' ('no rows affected') that Perl treats as zero but regards as true:
+                or die "Could not perform\n\t$sql\nwith data:\n\t(".join(',', @$non_autoinc_values).')';
+            if($return_code > 0) {     # <--- for the same reason we have to be expliticly numeric here
+                if($autoinc_id) {
+                    if($object_class) {
+                        $object->dbID( $sth->{'mysql_insertid'} );
+                    } else {
+                        $object->{$autoinc_id} = $sth->{'mysql_insertid'};
+                    }
+                }
+            }
+        }
+        if($object_class) {
+            $object->adaptor($self);
+        }
+    }
+
+    $sth->finish();
+
+    return $object_or_list;
+}
+
+
+sub create_new {
+    my $self = shift @_;
+
+    my $check_presence_in_db_first = (scalar(@_)%2)
+        ? pop @_    # extra 'odd' parameter that would disrupt the hash integrity anyway
+        : 0;        # do not check by default
+
+    my $object;
+
+    if( my $object_class = $self->object_class() ) {
+        $object = $object_class->new( -adaptor => $self, @_ );
+    } else {
+        $object = { @_ };
+    }
+
+    return $self->store( $object, $check_presence_in_db_first );
+}
+
+
+sub DESTROY { }   # to simplify AUTOLOAD
+
+sub AUTOLOAD {
+    our $AUTOLOAD;
+
+    if($AUTOLOAD =~ /::fetch_(all_)?by_(\w+)$/) {
+        my $all         = $1;
+        my $filter_name = $2;
+
+        my ($self) = @_;
+        my $column_set = $self->column_set();
+
+        my @columns_to_fetch_by = split('_and_', $filter_name);
+        foreach my $column_name (@columns_to_fetch_by) {
+            unless($column_set->{$column_name}) {
+                die "unknown column '$column_name'";
+            }
+        }
+
+        print "Setting up '$AUTOLOAD' method\n";
+        if($all) {
+            *$AUTOLOAD = sub { my $self = shift @_; return $self->fetch_all( join(' AND ', map { "$columns_to_fetch_by[$_]='$_[$_]'" } 0..scalar(@columns_to_fetch_by)-1) ); };
+        } else {
+            *$AUTOLOAD = sub { my $self = shift @_; my ($object) = @{ $self->fetch_all( join(' AND ', map { "$columns_to_fetch_by[$_]='$_[$_]'" } 0..scalar(@columns_to_fetch_by)-1) ) }; return $object; };
+        }
+        goto &$AUTOLOAD;    # restart the new method
+    } elsif($AUTOLOAD =~ /::count_all_by_(\w+)$/) {
+        my $filter_name = $1;
+
+        my ($self) = @_;
+        my $column_set = $self->column_set();
+
+        if($column_set->{$filter_name}) {
+            print "Setting up '$AUTOLOAD' method\n";
+            *$AUTOLOAD = sub { my ($self, $filter_value) = @_; return $self->count_all("$filter_name='$filter_value'"); };
+            goto &$AUTOLOAD;    # restart the new method
+        } else {
+            die "unknown column '$filter_name'";
+        }
+    } elsif($AUTOLOAD =~ /::update_(\w+)$/) {
+        my @columns_to_update = split('_and_', $1);
+        print "Setting up '$AUTOLOAD' method\n";
+        *$AUTOLOAD = sub { my ($self, $object) = @_; return $self->update($object, @columns_to_update); };
+        goto &$AUTOLOAD;    # restart the new method
+    } else {
+        print "sub '$AUTOLOAD' not implemented";
+    }
+}
+
+1;
+
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/DBAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/DBAdaptor.pm
index ba1602c60278c7ccf5547e7f560218c3af8051f6..4faa535e83bea6eed4540e94615348dfce870b61 100755
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/DBAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/DBAdaptor.pm
@@ -45,18 +45,21 @@ sub get_available_adaptors {
             # Core adaptors extended with Hive stuff:
         'MetaContainer'       => 'Bio::EnsEMBL::Hive::DBSQL::MetaContainer',
         'Analysis'            => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor',
-            # Hive adaptors:
-        'Queen'               => 'Bio::EnsEMBL::Hive::Queen',
-        'AnalysisJob'         => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisJobAdaptor',
-        'AnalysisData'        => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisDataAdaptor',
-        'AnalysisStats'       => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisStatsAdaptor',
+
+            # "new" Hive adaptors (sharing the same fetching/storing code inherited from the BaseAdaptor class) :
         'AnalysisCtrlRule'    => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisCtrlRuleAdaptor',
         'DataflowRule'        => 'Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor',
         'ResourceDescription' => 'Bio::EnsEMBL::Hive::DBSQL::ResourceDescriptionAdaptor',
-        'NakedTable'          => 'Bio::EnsEMBL::Hive::DBSQL::NakedTableAdaptor',
         'JobMessage'          => 'Bio::EnsEMBL::Hive::DBSQL::JobMessageAdaptor',
+        'NakedTable'          => 'Bio::EnsEMBL::Hive::DBSQL::NakedTableAdaptor',
+
+            # "old" Hive adaptors (having their own fetching/storing code) :
+        'Queen'               => 'Bio::EnsEMBL::Hive::Queen',
+        'AnalysisJob'         => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisJobAdaptor',
+        'AnalysisStats'       => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisStatsAdaptor',
+        'AnalysisData'        => 'Bio::EnsEMBL::Hive::DBSQL::AnalysisDataAdaptor',
     );
-    return (\%pairs);
+    return \%pairs;
 }
  
 1;
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/DataflowRuleAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/DataflowRuleAdaptor.pm
index 9723c295819bfee4a6a7873a2f0ab09ca97a8f36..1b497fd86b3d1f9a4d93b1422bc7d32c62f1b38a 100755
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/DataflowRuleAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/DataflowRuleAdaptor.pm
@@ -1,12 +1,3 @@
-# Perl module for Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor
-#
-# Date of creation: 22.03.2004
-# Original Creator : Jessica Severin <jessica@ebi.ac.uk>
-#
-# Copyright EMBL-EBI 2004
-#
-# You may distribute this module under the same terms as perl itself
-
 =pod
 
 =head1 NAME
@@ -15,8 +6,8 @@
 
 =head1 SYNOPSIS
 
-  $dataflowRuleAdaptor = $db_adaptor->get_DataflowRuleAdaptor;
-  $dataflowRuleAdaptor = $dataflowRuleObj->adaptor;
+  $dataflow_rule_adaptor = $db_adaptor->get_DataflowRuleAdaptor;
+  $dataflow_rule_adaptor = $dataflowRuleObj->adaptor;
 
 =head1 DESCRIPTION
 
@@ -27,24 +18,34 @@
 
   Please contact ehive-users@ebi.ac.uk mailing list with questions/suggestions.
 
-=head1 APPENDIX
-
-  The rest of the documentation details each of the object methods.
-  Internal methods are usually preceded with a _
-  
 =cut
 
 
 package Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor;
 
 use strict;
-use Carp;
 use Bio::EnsEMBL::Hive::DataflowRule;
-use Bio::EnsEMBL::Utils::Argument;
-use Bio::EnsEMBL::Utils::Exception;
 use Bio::EnsEMBL::Hive::Utils ('stringify');  # import 'stringify()'
 
-use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
+use base ('Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor');
+
+
+sub default_table_name {
+    return 'dataflow_rule';
+}
+
+
+sub default_insertion_method {
+    return 'INSERT';
+}
+
+
+sub object_class {
+    return 'Bio::EnsEMBL::Hive::DataflowRule';
+}
+
+
+
 
 =head2 branch_name_2_code
 
@@ -88,105 +89,9 @@ sub fetch_all_by_from_analysis_id_and_branch_code {
 
     my $branch_code = $self->branch_name_2_code($branch_name_or_code);
 
-    my $constraint = "r.from_analysis_id=${analysis_id} AND r.branch_code=${branch_code}";
-
-    return $self->_generic_fetch($constraint);
-}
-
-sub check_rule_exists_in_db {
-    my ( $self, $rule ) = @_;
-
-    my $from_analysis_id  = $rule->from_analysis_id;
-    my $to_analysis_url   = $rule->to_analysis_url;
-    my $branch_code       = $rule->branch_code;
-    my $input_id_template = ref($rule->input_id_template) ? stringify($rule->input_id_template) : $rule->input_id_template;
-
-    my $sql = qq{
-        SELECT dataflow_rule_id
-          FROM dataflow_rule
-         WHERE from_analysis_id='$from_analysis_id'
-           AND to_analysis_url='$to_analysis_url'
-           AND branch_code='$branch_code'
-           AND input_id_template
-    } . ( defined($input_id_template) ? "='$input_id_template'" : "IS NULL" );
-
-    my $sth = $self->prepare($sql);
-    $sth->execute();
-
-    if(my ($dataflow_rule_id) = $sth->fetchrow()) {
-        $sth->finish;
-        return $dataflow_rule_id;
-    } else {
-        $sth->finish;
-        return 0;
-    }
-}
-
-=head2 store
+    my $constraint = "from_analysis_id=${analysis_id} AND branch_code=${branch_code}";
 
-  Usage   : $self->store( $rule );
-  Function: Stores a rule in db
-            Sets adaptor and dbID in DataflowRule
-  Returns : -
-  Args    : Bio::EnsEMBL::Hive::DataflowRule
-
-=cut
-
-sub store {
-    my ( $self, $rule ) = @_;
-
-    my $dataflow_rule_id;
-
-    if($dataflow_rule_id = $self->check_rule_exists_in_db($rule)) {
-
-        $rule->dbID($dataflow_rule_id);
-        $rule->adaptor( $self );
-        return 0;
-
-    } else {
-        
-        my $from_analysis_id  = $rule->from_analysis_id;
-        my $to_analysis_url   = $rule->to_analysis_url;
-        my $branch_code       = $rule->branch_code;
-        my $input_id_template = ref($rule->input_id_template) ? stringify($rule->input_id_template) : $rule->input_id_template;
-
-        my $sth = $self->prepare("INSERT INTO dataflow_rule (from_analysis_id, to_analysis_url, branch_code, input_id_template) VALUES (?,?,?,?)");
-
-        my $rtnCode = $sth->execute($from_analysis_id, $to_analysis_url, $branch_code, $input_id_template);
-
-        if($rtnCode and ($rtnCode != 0E0)) {   # we managed to insert a new row (0E0 would indicate success when no rows were inserted)
-            $dataflow_rule_id = $sth->{'mysql_insertid'};
-            $sth->finish();
-            $rule->dbID($dataflow_rule_id);
-            $rule->adaptor( $self );
-            return 1;
-        } else {
-            die "Could not create a dataflow_rule('$from_analysis_id', '$to_analysis_url', '$branch_code', '$input_id_template')";
-        }
-    }
-}
-
-
-=head2 remove
-
-  Title   : remove
-  Usage   : $self->remove( $rule );
-  Function: removes given object from database.
-  Returns : -
-  Args    : Bio::EnsEMBL::Hive::DataflowRule which must be persistent with a valid dbID
-            
-=cut
-
-sub remove {
-  my ( $self, $rule ) = @_;
-
-  my $dbID = $rule->dbID;
-  if( !defined $dbID ) {
-    throw( "DataflowRuleAdaptor->remove called with non persistent DataflowRule" );
-  }
-
-  my $sth = $self->prepare("DELETE FROM dataflow_rule WHERE dataflow_rule_id = $dbID");
-  $sth->execute;
+    return $self->fetch_all($constraint);
 }
 
 
@@ -216,180 +121,12 @@ sub create_rule {
             : ( -to_analysis_url => $to_analysis_or_url ),
 
         -branch_code        =>  $self->branch_name_2_code($branch_name_or_code),
-        -input_id_template  =>  $input_id_template,
+        -input_id_template  =>  (ref($input_id_template) ? stringify($input_id_template) : $input_id_template),
     );
 
-    return $self->store($rule);
+    return $self->store($rule, 1);  # avoid redundancy
 }
 
-############################
-#
-# INTERNAL METHODS
-# (pseudo subclass methods)
-#
-############################
-
-#internal method used in multiple calls above to build objects from table data
-
-sub _tables {
-  my $self = shift;
-
-  return (['dataflow_rule', 'r']);
-}
-
-
-sub _columns {
-  my $self = shift;
-
-  return qw (r.dataflow_rule_id
-             r.from_analysis_id
-             r.to_analysis_url
-             r.branch_code
-             r.input_id_template
-            );
-}
-
-
-sub _objs_from_sth {
-  my ($self, $sth) = @_;
-  my @rules = ();
-
-  my ($dataflow_rule_id, $from_analysis_id, $to_analysis_url, $branch_code, $input_id_template);
-  $sth->bind_columns(\$dataflow_rule_id, \$from_analysis_id, \$to_analysis_url, \$branch_code, \$input_id_template);
-
-  while ($sth->fetch()) {
-    my $rule = Bio::EnsEMBL::Hive::DataflowRule->new(
-        -dbID               =>  $dataflow_rule_id,
-        -adaptor            =>  $self,
-
-        -from_analysis_id   =>  $from_analysis_id,
-        -to_analysis_url    =>  $to_analysis_url,
-        -branch_code        =>  $branch_code,
-        -input_id_template  =>  $input_id_template,
-    );
-    push @rules, $rule;
-  }
-  return \@rules;
-}
-
-sub _default_where_clause {
-  my $self = shift;
-  return '';
-}
-
-sub _final_clause {
-  my $self = shift;
-  return '';
-}
-
-###############################################################################
-#
-# General access methods that could be moved
-# into a superclass
-#
-###############################################################################
-
-=head2 fetch_by_dbID
-  
-  Arg [1]    : int $id
-               the unique database identifier for the feature to be obtained
-  Example    : $feat = $adaptor->fetch_by_dbID(1234);
-  Description: Returns the Member created from the database defined by the
-               the id $id.
-  Returntype : Bio::EnsEMBL::Hive::DataflowRule
-  Exceptions : thrown if $id is not defined
-  Caller     : general
-  
-=cut
-
-sub fetch_by_dbID {
-  my ($self,$id) = @_;
-
-  unless(defined $id) {
-    throw("fetch_by_dbID must have an id");
-  }
-
-  my @tabs = $self->_tables;
-
-  my ($name, $syn) = @{$tabs[0]};
-
-  #construct a constraint like 't1.table1_id = 1'
-  my $constraint = "${syn}.${name}_id = $id";
-
-  #return first element of _generic_fetch list
-  my ($obj) = @{$self->_generic_fetch($constraint)};
-  return $obj;
-}
-
-
-=head2 fetch_all
-
-  Arg        : None
-  Example    :
-  Description:
-  Returntype :
-  Exceptions :
-  Caller     :
-
-=cut
-
-sub fetch_all {
-  my $self = shift;
-  return $self->_generic_fetch();
-}
-
-sub _generic_fetch {
-  my ($self, $constraint, $join) = @_;
-
-  my @tables = $self->_tables;
-  my $columns = join(', ', $self->_columns());
-
-  if ($join) {
-    foreach my $single_join (@{$join}) {
-      my ($tablename, $condition, $extra_columns) = @{$single_join};
-      if ($tablename && $condition) {
-        push @tables, $tablename;
-
-        if($constraint) {
-          $constraint .= " AND $condition";
-        } else {
-          $constraint = " $condition";
-        }
-      }
-      if ($extra_columns) {
-        $columns .= ", " . join(', ', @{$extra_columns});
-      }
-    }
-  }
-
-  #construct a nice table string like 'table1 t1, table2 t2'
-  my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
-
-  my $sql = "SELECT $columns FROM $tablenames";
-
-  my $default_where = $self->_default_where_clause;
-  my $final_clause = $self->_final_clause;
-
-  #append a where clause if it was defined
-  if($constraint) {
-    $sql .= " WHERE $constraint ";
-    if($default_where) {
-      $sql .= " AND $default_where ";
-    }
-  } elsif($default_where) {
-    $sql .= " WHERE $default_where ";
-  }
-
-  #append additional clauses which may have been defined
-  $sql .= " $final_clause";
-
-  my $sth = $self->prepare($sql);
-  $sth->execute;
-
-#  print STDERR $sql,"\n";
-
-  return $self->_objs_from_sth($sth);
-}
 
 1;
 
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/JobMessageAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/JobMessageAdaptor.pm
index 4be41bbcb6840dadbe4395ad38a01c50785498cb..4c46218a695d0c47bf019fa6a7895ac10c0af936 100644
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/JobMessageAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/JobMessageAdaptor.pm
@@ -10,7 +10,7 @@
 
 =head1 DESCRIPTION
 
-    This is currently an "objectless" adaptor that simply helps to store messages thrown by jobs into job_message table.
+    This is currently an "objectless" adaptor that helps to store either warning-messages or die-messages generated by jobs
 
 =head1 CONTACT
 
@@ -23,16 +23,24 @@ package Bio::EnsEMBL::Hive::DBSQL::JobMessageAdaptor;
 
 use strict;
 
-use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
+use base ('Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor');
+
+
+sub default_table_name {
+    return 'job_message';
+}
+
 
 sub register_message {
     my ($self, $job_id, $msg, $is_error) = @_;
 
     chomp $msg;   # we don't want that last "\n" in the database
 
+    my $table_name = $self->table_name();
+
         # (the timestamp 'moment' column will be set automatically)
     my $sql = qq{
-        REPLACE INTO job_message (job_id, worker_id, analysis_id, retry_count, status, msg, is_error)
+        REPLACE INTO $table_name (job_id, worker_id, analysis_id, retry_count, status, msg, is_error)
                            SELECT job_id, worker_id, analysis_id, retry_count, status, ?, ?
                              FROM job WHERE job_id=?
     };
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/NakedTableAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/NakedTableAdaptor.pm
index 0317188cdf15082515ffdcd9b4b31a9aeb682e30..e857b90ee6e72243943456ede44ccedc1cc96326 100644
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/NakedTableAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/NakedTableAdaptor.pm
@@ -7,14 +7,12 @@
 =head1 SYNOPSIS
 
     $naked_table_adaptor = $dba->get_NakedTableAdaptor;
-
     $naked_table_adaptor = $naked_table->adaptor;
 
 =head1 DESCRIPTION
 
-    This module together with its data container are used to enable dataflow into arbitrary tables (rather than just job).
-
-    NakedTable objects know *where* to dataflow, and NakedTableAdaptor knows *how* to dataflow.
+    This module together with its data container are used to enable dataflow into arbitrary tables (rather than just 'job' table).
+    Due to the implementation of EnsEMBL Registry code, NakedTable objects know *where* to dataflow, and NakedTableAdaptor knows *how* to dataflow.
 
 =head1 CONTACT
 
@@ -28,43 +26,10 @@ package Bio::EnsEMBL::Hive::DBSQL::NakedTableAdaptor;
 use strict;
 use Bio::EnsEMBL::Hive::NakedTable;
 
-use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
-
-sub create_new {
-    my $self = shift @_;
-
-    return Bio::EnsEMBL::Hive::NakedTable->new(@_, -ADAPTOR => $self);
-}
-
-sub dataflow {
-    my ( $self, $naked_table, $output_ids ) = @_;
-
-    return unless(@$output_ids);
-
-    my $table_name = $naked_table->table_name();
-
-    my $insertion_method = uc( $naked_table->insertion_method() );  # INSERT, INSERT_IGNORE or REPLACE
-    $insertion_method =~ s/_/ /g;
-
-        # NB: here we assume all hashes will have the same keys (and also the same order):
-    my @column_names = keys %{$output_ids->[0]};
-
-        # By using question marks you can insert true NULLs by setting corresponding values to undefs:
-    my $sql = "$insertion_method INTO $table_name (".join(', ', @column_names).') VALUES ('.join(',', (('?') x scalar(@column_names))).')';
-    my $sth = $self->prepare( $sql );
-
-    my @insert_ids = ();
-
-    foreach my $data_hash (@$output_ids) {
-        $sth->execute( values %$data_hash ); # Perl manual promises that the order of "keys" will be the same as the order of "values", so no need to sort.
-        push @insert_ids, $sth->{'mysql_insertid'}; # capture it just in case
-
-    }
-
-    $sth->finish();
+use base ('Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor');
 
-    return \@insert_ids;
-}
+# No, you could not just use the Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor instead of NakedTableAdaptor
+# because AUTOLOAD will be creating class-specific methods and you don't want to clutter BaseAdaptor's namespace.
 
 1;
 
diff --git a/modules/Bio/EnsEMBL/Hive/DBSQL/ResourceDescriptionAdaptor.pm b/modules/Bio/EnsEMBL/Hive/DBSQL/ResourceDescriptionAdaptor.pm
index e15c3625c76f804bf229c9a67f06e6420298c808..1bbb3a250c6a4bdcf524eb55f44bc5130acd758f 100644
--- a/modules/Bio/EnsEMBL/Hive/DBSQL/ResourceDescriptionAdaptor.pm
+++ b/modules/Bio/EnsEMBL/Hive/DBSQL/ResourceDescriptionAdaptor.pm
@@ -27,169 +27,21 @@ package Bio::EnsEMBL::Hive::DBSQL::ResourceDescriptionAdaptor;
 use strict;
 use Bio::EnsEMBL::Hive::ResourceDescription;
 
-use base ('Bio::EnsEMBL::DBSQL::BaseAdaptor');
+use base ('Bio::EnsEMBL::Hive::DBSQL::BaseAdaptor');
 
-sub fetch_by_rcid_meadowtype {
-    my ($self, $rc_id, $meadow_type) = @_;
 
-    my $constraint = "rd.rc_id = $rc_id AND rd.meadow_type = '$meadow_type'";
-    my ($rd) = @{ $self->_generic_fetch($constraint) };
-
-    return $rd;     # returns one object or undef
-}
-
-sub fetch_all_by_meadowtype {
-    my ($self, $meadow_type) = @_;
-
-    my $constraint = "rd.meadow_type = '$meadow_type'";
-    return $self->_generic_fetch($constraint);      # returns an arrayref
-}
-
-sub store {
-    my ( $self, $rd ) = @_;
-
-    my $sth = $self->prepare( q{REPLACE INTO resource_description (rc_id, meadow_type, parameters, description) VALUES (?,?,?,?) } );
-    $sth->execute($rd->rc_id, $rd->meadow_type, $rd->parameters, $rd->description);
-    $sth->finish();
-
-    return $rd;
-}
-
-sub remove {
-    my ( $self, $rd ) = @_;
-
-    my $sth = $self->prepare( q{DELETE FROM resource_description WHERE rc_id = ? AND meadow_type = ?} );
-    $sth->execute($rd->rc_id, $rd->meadow_type);
-    $sth->finish();
+sub default_table_name {
+    return 'resource_description';
 }
 
-sub create_new {
-    my $self = shift @_;
 
-    my $rd = Bio::EnsEMBL::Hive::ResourceDescription->new(@_, -ADAPTOR => $self);
-    return $self->store($rd);
+sub default_insertion_method {
+    return 'REPLACE';
 }
 
-############################
-#
-# INTERNAL METHODS
-# (pseudo subclass methods)
-#
-############################
-
-#internal method used in multiple calls above to build objects from table data
-
-sub _tables {
-    my $self = shift;
-
-    return (['resource_description', 'rd']);
-}
-
-
-sub _columns {
-    my $self = shift;
-
-    return qw (rd.rc_id
-             rd.meadow_type
-             rd.parameters
-             rd.description
-    );
-}
-
-
-sub _objs_from_sth {
-    my ($self, $sth) = @_;
-    my @rds = ();
-
-    while(my ($rc_id, $meadow_type, $parameters, $description) = $sth->fetchrow_array) {
-        my $rd = Bio::EnsEMBL::Hive::ResourceDescription->new(
-            -ADAPTOR     => $self,
-            -RC_ID       => $rc_id,
-            -MEADOW_TYPE => $meadow_type,
-            -PARAMETERS  => $parameters,
-            -DESCRIPTION => $description,
-        );
-        push @rds, $rd;
-    }
-    return \@rds;
-}
-
-
-sub _default_where_clause {
-    my $self = shift;
-    return '';
-}
-
-
-sub _final_clause {
-    my $self = shift;
-    return '';
-}
-
-###############################################################################
-#
-# General access methods that could be moved
-# into a superclass
-#
-###############################################################################
-
-sub fetch_all {
-    my $self = shift;
-    return $self->_generic_fetch();
-}
-
-
-sub _generic_fetch {
-  my ($self, $constraint, $join) = @_;
-
-  my @tables = $self->_tables;
-  my $columns = join(', ', $self->_columns());
-
-  if ($join) {
-    foreach my $single_join (@{$join}) {
-      my ($tablename, $condition, $extra_columns) = @{$single_join};
-      if ($tablename && $condition) {
-        push @tables, $tablename;
-
-        if($constraint) {
-          $constraint .= " AND $condition";
-        } else {
-          $constraint = " $condition";
-        }
-      }
-      if ($extra_columns) {
-        $columns .= ", " . join(', ', @{$extra_columns});
-      }
-    }
-  }
-
-  #construct a nice table string like 'table1 t1, table2 t2'
-  my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
-
-  my $sql = "SELECT $columns FROM $tablenames";
-
-  my $default_where = $self->_default_where_clause;
-  my $final_clause = $self->_final_clause;
-
-  #append a where clause if it was defined
-  if($constraint) {
-    $sql .= " WHERE $constraint ";
-    if($default_where) {
-      $sql .= " AND $default_where ";
-    }
-  } elsif($default_where) {
-    $sql .= " WHERE $default_where ";
-  }
-
-  #append additional clauses which may have been defined
-  $sql .= " $final_clause";
-
-  my $sth = $self->prepare($sql);
-  $sth->execute;
-
-#  print STDERR $sql,"\n";
 
-  return $self->_objs_from_sth($sth);
+sub object_class {
+    return 'Bio::EnsEMBL::Hive::ResourceDescription';
 }
 
 1;
diff --git a/modules/Bio/EnsEMBL/Hive/NakedTable.pm b/modules/Bio/EnsEMBL/Hive/NakedTable.pm
index 57e7ad7c18410e60808a8347b7f29e47d90d3f92..a080b092d4cb4d5b5d39cc2957414b3c97ea3cb1 100644
--- a/modules/Bio/EnsEMBL/Hive/NakedTable.pm
+++ b/modules/Bio/EnsEMBL/Hive/NakedTable.pm
@@ -79,7 +79,14 @@ sub url {
 sub dataflow {
     my ( $self, $output_ids ) = @_;
 
-    return $self->adaptor->dataflow($self, $output_ids);
+        # we have to do this the ugly way
+        # because Registry code currently prevents us from passing arguments to adaptors' new() methods
+        # (and by caching guarantees there is only one instance of each adaptor per DBAdaptor)
+    my $adaptor = $self->adaptor();
+    $adaptor->table_name( $self->table_name() );
+    $adaptor->insertion_method( $self->insertion_method() );
+
+    $adaptor->store( $output_ids );
 }
 
 
diff --git a/modules/Bio/EnsEMBL/Hive/PipeConfig/HiveGeneric_conf.pm b/modules/Bio/EnsEMBL/Hive/PipeConfig/HiveGeneric_conf.pm
index dba09f51485d2bf8c24a7e859f69209a2c68d443..fb0ee5348e4d4ab5eabeafc124d97b090c17904c 100644
--- a/modules/Bio/EnsEMBL/Hive/PipeConfig/HiveGeneric_conf.pm
+++ b/modules/Bio/EnsEMBL/Hive/PipeConfig/HiveGeneric_conf.pm
@@ -345,8 +345,8 @@ sub run {
     my $analysis_adaptor             = $hive_dba->get_AnalysisAdaptor;
 
     foreach my $aha (@{$self->pipeline_analyses}) {
-        my ($logic_name, $module, $parameters_hash, $input_ids, $program_file, $blocked, $batch_size, $hive_capacity, $failed_job_tolerance, $can_be_empty, $rc_id) =
-             rearrange([qw(logic_name module parameters input_ids program_file blocked batch_size hive_capacity failed_job_tolerance can_be_empty rc_id)], %$aha);
+        my ($logic_name, $module, $parameters_hash, $input_ids, $program_file, $blocked, $batch_size, $hive_capacity, $failed_job_tolerance, $max_retry_count, $can_be_empty, $rc_id) =
+             rearrange([qw(logic_name module parameters input_ids program_file blocked batch_size hive_capacity failed_job_tolerance max_retry_count can_be_empty rc_id)], %$aha);
 
         $parameters_hash ||= {};
         $input_ids       ||= [];
@@ -382,6 +382,7 @@ sub run {
             $stats->batch_size( $batch_size )                       if(defined($batch_size));
             $stats->hive_capacity( $hive_capacity )                 if(defined($hive_capacity));
             $stats->failed_job_tolerance( $failed_job_tolerance )   if(defined($failed_job_tolerance));
+            $stats->max_retry_count( $max_retry_count )             if(defined($max_retry_count));
             $stats->rc_id( $rc_id )                                 if(defined($rc_id));
             $stats->can_be_empty( $can_be_empty )                   if(defined($can_be_empty));
             $stats->status($blocked ? 'BLOCKED' : 'READY');         #   (some analyses will be waiting for human intervention in blocked state)
@@ -419,10 +420,9 @@ sub run {
             foreach my $condition_url (@$wait_for) {
                 if(my $condition_analysis = $analysis_adaptor->fetch_by_logic_name_or_url($condition_url)) {
 
-                    my $new_cfr    = $ctrl_rule_adaptor->create_rule( $condition_analysis, $analysis);
-                    my $cfr_action = $new_cfr ? 'Created a new' : 'Found an existing';
+                    $ctrl_rule_adaptor->create_rule( $condition_analysis, $analysis);
 
-                    warn "$cfr_action Control rule: $condition_url -| $logic_name\n";
+                    warn "Control rule: $condition_url -| $logic_name\n";
                 } else {
                     die "Could not fetch analysis '$condition_url' to create a control rule";
                 }
@@ -442,10 +442,9 @@ sub run {
 
                     my $heir_analysis = $analysis_adaptor->fetch_by_logic_name_or_url($heir_url);
 
-                    my $new_dfr    = $dataflow_rule_adaptor->create_rule( $analysis, $heir_analysis || $heir_url, $branch_name_or_code, $input_id_template);
-                    my $dfr_action = $new_dfr ? 'Created a new' : 'Found an existing';
+                    $dataflow_rule_adaptor->create_rule( $analysis, $heir_analysis || $heir_url, $branch_name_or_code, $input_id_template);
 
-                    warn "$dfr_action DataFlow rule: [$branch_name_or_code] $logic_name -> $heir_url"
+                    warn "DataFlow rule: [$branch_name_or_code] $logic_name -> $heir_url"
                         .($input_id_template ? ' WITH TEMPLATE: '.stringify($input_id_template) : '')."\n";
                 }
             }
diff --git a/modules/Bio/EnsEMBL/Hive/RunnableDB/LongMult/Start.pm b/modules/Bio/EnsEMBL/Hive/RunnableDB/LongMult/Start.pm
index 5f1f3619102fe24aff2fd89c9e010c891c5fd889..e1ae57973c0d9bf57a9f588a7e4f34a0d8ccb190 100644
--- a/modules/Bio/EnsEMBL/Hive/RunnableDB/LongMult/Start.pm
+++ b/modules/Bio/EnsEMBL/Hive/RunnableDB/LongMult/Start.pm
@@ -84,6 +84,8 @@ sub write_output {  # nothing to write out, but some dataflow to perform:
         # "fan out" into branch#2 first
     $self->dataflow_output_id($output_ids, 2);
 
+    $self->warning(scalar(@$output_ids).' multiplication jobs have been created');     # warning messages get recorded into 'job_message' table
+
         # then flow into the MAIN branch funnel; input_id would flow into MAIN branch by default anyway, but we request it here explicitly:
     $self->dataflow_output_id($self->input_id, 'MAIN');
 }
diff --git a/modules/Bio/EnsEMBL/Hive/URLFactory.pm b/modules/Bio/EnsEMBL/Hive/URLFactory.pm
index e30b210e8a9aaf1e0b2d400fb9023f85c492a829..6f5df42e87f1898c0510e2ed477320fd32bf2224 100755
--- a/modules/Bio/EnsEMBL/Hive/URLFactory.pm
+++ b/modules/Bio/EnsEMBL/Hive/URLFactory.pm
@@ -48,6 +48,7 @@ use Bio::EnsEMBL::Hive::Extensions;
 use Bio::EnsEMBL::DBSQL::AnalysisAdaptor;
 use Bio::EnsEMBL::DBSQL::DBAdaptor;
 use Bio::EnsEMBL::Hive::DBSQL::DBAdaptor;
+use Bio::EnsEMBL::Hive::NakedTable;
 
 #use Data::Dumper;
 
@@ -112,7 +113,11 @@ sub fetch {
 
         } else {
 
-            return $dba->get_NakedTableAdaptor->create_new(-table_name => $table_name, $tparam_value ? (-insertion_method => $tparam_value) : () );
+            return Bio::EnsEMBL::Hive::NakedTable->new(
+                -adaptor    => $dba->get_NakedTableAdaptor,
+                -table_name => $table_name,
+                $tparam_value ? (-insertion_method => $tparam_value) : ()
+            );
         }
     }
     return;
diff --git a/scripts/beekeeper.pl b/scripts/beekeeper.pl
index 6e43e25a1aefb580edca3b238d980f4ef57a0d19..83bf6462fa50c47cd97cf848b53d54ad0fc6af95 100755
--- a/scripts/beekeeper.pl
+++ b/scripts/beekeeper.pl
@@ -366,7 +366,7 @@ sub run_autonomously {
 
         # pre-hash the resource_class xparams for future use:
     my %rc_xparams = map { ($_->rc_id => $_->parameters) }
-        @{ $self->{'dba'}->get_ResourceDescriptionAdaptor->fetch_all_by_meadowtype($self->{'meadow'}->type()) };
+        @{ $self->{'dba'}->get_ResourceDescriptionAdaptor->fetch_all_by_meadow_type($self->{'meadow'}->type()) };
 
     my $iteration=0;
     my $num_of_remaining_jobs=0;