diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index b65a8291062f723a6f33f741da6f6208e5efa8a8..d41d1b74ca7e0f33d5cc6dad2d1f4b921b0c4daf 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -323,17 +323,17 @@ execute stmt4;
 Engine	Support	Comment
 MyISAM	YES/NO	Default engine as of MySQL 3.23 with great performance
 MEMORY	YES/NO	Hash based, stored in memory, useful for temporary tables
-MRG_MYISAM	YES/NO	Collection of identical MyISAM tables
-ISAM	YES/NO	Obsolete storage engine, now replaced by MyISAM
-MRG_ISAM	YES/NO	Obsolete storage engine, now replaced by MERGE
 InnoDB	YES/NO	Supports transactions, row-level locking, and foreign keys
-BERKELEYDB	YES/NO	Supports transactions and page-level locking
-NDBCLUSTER	YES/NO	Clustered, fault-tolerant, memory-based tables
+BerkeleyDB	YES/NO	Supports transactions and page-level locking
+BLACKHOLE	YES/NO	/dev/null storage engine (anything you write to it disappears)
 EXAMPLE	YES/NO	Example storage engine
 ARCHIVE	YES/NO	Archive storage engine
 CSV	YES/NO	CSV storage engine
+ndbcluster	YES/NO	Clustered, fault-tolerant, memory-based tables
 FEDERATED	YES/NO	Federated MySQL storage engine
-BLACKHOLE	YES/NO	/dev/null storage engine (anything you write to it disappears)
+MRG_MYISAM	YES/NO	Collection of identical MyISAM tables
+binlog	YES/NO	This is a meta storage engine to represent the binlog in a transaction
+ISAM	YES/NO	Obsolete storage engine
 drop table if exists t5;
 prepare stmt1 from ' drop table if exists t5 ' ;
 execute stmt1 ;
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index 86e6ae8a2de839624a019997533b2c81fa6c67fa..541e91f4b46ae1dcb334d367292c244ab7ed545a 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -861,21 +861,6 @@ THR_LOCK_DATA **ha_tina::store_lock(THD *thd,
   return to;
 }
 
-/* 
-  Range optimizer calls this.
-  I need to update the information on this.
-*/
-ha_rows ha_tina::records_in_range(int inx,
-                                  const byte *start_key,uint start_key_len,
-                                  enum ha_rkey_function start_search_flag,
-                                  const byte *end_key,uint end_key_len,
-                                  enum ha_rkey_function end_search_flag)
-{
-  DBUG_ENTER("ha_tina::records_in_range ");
-  DBUG_RETURN(records); // Good guess
-}
-
-
 /* 
   Create a table. You do not want to leave the table open after a call to
   this (the database will call ::open() if it needs to).
diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h
index 1ccb34187718257dc06246fe0af26477fc6044e5..84854e868fab63f6fbc8e89bf3f9c0a0dd308ef3 100644
--- a/sql/examples/ha_tina.h
+++ b/sql/examples/ha_tina.h
@@ -78,7 +78,6 @@ public:
    */
   virtual double scan_time() { return (double) (records+deleted) / 20.0+10; }
   /* The next method will never be called */
-  virtual double read_time(ha_rows rows) { DBUG_ASSERT(0); return((double) rows /  20.0+1); }
   virtual bool fast_key_read() { return 1;}
   /* 
     TODO: return actual upper bound of number of records in the table.
@@ -110,12 +109,6 @@ public:
   int reset(void);
   int external_lock(THD *thd, int lock_type);
   int delete_all_rows(void);
-  ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len,
-      enum ha_rkey_function start_search_flag,
-      const byte *end_key,uint end_key_len,
-      enum ha_rkey_function end_search_flag);
-//  int delete_table(const char *from);
-//  int rename_table(const char * from, const char * to);
   int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
 
   THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index bc066b672d3b430cf8020ab6ad13564355279653..59c56e80cc33bc5b27621cefb1239336c8eed107 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -137,7 +137,7 @@ static HASH archive_open_tables;
 
 /* dummy handlerton - only to have something to return from archive_db_init */
 handlerton archive_hton = {
-  "archive",
+  "ARCHIVE",
   SHOW_OPTION_YES,
   "Archive storage engine", 
   DB_TYPE_ARCHIVE_DB,
@@ -201,7 +201,6 @@ bool archive_db_init()
   }
 error:
   have_archive_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
-  archive_hton.state= SHOW_OPTION_DISABLED;
   DBUG_RETURN(TRUE);
 }
 
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 60dd27efa69b0811f31bcda322b25cfd327d5333..c7e56b350bf1d42d6ab2ec3f080db90451b28e65 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -210,7 +210,6 @@ bool berkeley_init(void)
   DBUG_RETURN(FALSE);
 error:
   have_berkeley_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
-  berkeley_hton.state= SHOW_OPTION_DISABLED;
   DBUG_RETURN(TRUE);
 }
 
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index c129cb3058cdb79d2b1b61a226d72b3f5d1389b1..2b2be71cf53c0a36aedef2889638564f43b6ca2a 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -428,7 +428,6 @@ bool federated_db_init()
   }
 error:
   have_federated_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
-  federated_hton.state= SHOW_OPTION_DISABLED;
   DBUG_RETURN(TRUE);
 }
 
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index ebe1e41f890814fcf5903647607c99452d23b4a0..1129251f06bd9043cf02c604f4c172512f594595 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -1423,7 +1423,6 @@ innobase_init(void)
 	DBUG_RETURN(FALSE);
 error:
         have_innodb= SHOW_OPTION_DISABLED;	// If we couldn't use handler
-        innobase_hton.state= SHOW_OPTION_DISABLED;
         DBUG_RETURN(TRUE);
 }
 
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 030f5881861eae57d4395815efe143e9965dec33..5451447ec438a60e9dc4f4850f48bde3ad678e32 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -4837,7 +4837,6 @@ ndbcluster_init_error:
     delete g_ndb_cluster_connection;
   g_ndb_cluster_connection= NULL;
   have_ndbcluster= SHOW_OPTION_DISABLED;	// If we couldn't use handler
-  ndbcluster_hton.state= SHOW_OPTION_DISABLED;
   DBUG_RETURN(TRUE);
 }
 
diff --git a/sql/handler.cc b/sql/handler.cc
index 211da341da18ba07c36ba75ed77527ca3becd776..d449a0b90f20b34d3ad857a074e5f61ec7521dcb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -25,37 +25,87 @@
 #include "ha_heap.h"
 #include "ha_myisam.h"
 #include "ha_myisammrg.h"
+
+
+/*
+  We have dummy hanldertons in case the handler has not been compiled
+  in. This will be removed in 5.1.
+*/
 #ifdef HAVE_BERKELEY_DB
 #include "ha_berkeley.h"
 extern handlerton berkeley_hton;
+#else
+handlerton berkeley_hton = { "BerkeleyDB", SHOW_OPTION_NO, 
+  "Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB, NULL, 
+  0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  NULL, NULL, HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_BLACKHOLE_DB
 #include "ha_blackhole.h"
 extern handlerton blackhole_hton;
+#else
+handlerton blackhole_hton = { "BLACKHOLE", SHOW_OPTION_NO,
+  "/dev/null storage engine (anything you write to it disappears)",
+  DB_TYPE_BLACKHOLE_DB, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_EXAMPLE_DB
 #include "examples/ha_example.h"
 extern handlerton example_hton;
+#else
+handlerton example_hton = { "EXAMPLE", SHOW_OPTION_NO,
+  "Example storage engine", 
+  DB_TYPE_EXAMPLE_DB, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_ARCHIVE_DB
 #include "ha_archive.h"
 extern handlerton archive_hton;
+#else
+handlerton archive_hton = { "ARCHIVE", SHOW_OPTION_NO,
+  "Archive storage engine", DB_TYPE_ARCHIVE_DB, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_CSV_DB
 #include "examples/ha_tina.h"
 extern handlerton tina_hton;
+#else
+handlerton tina_hton = { "CSV", SHOW_OPTION_NO, "CSV storage engine", 
+  DB_TYPE_CSV_DB, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_INNOBASE_DB
 #include "ha_innodb.h"
 extern handlerton innobase_hton;
+#else
+handlerton innobase_hton = { "InnoDB", SHOW_OPTION_NO,
+  "Supports transactions, row-level locking, and foreign keys", 
+  DB_TYPE_INNODB, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_NDBCLUSTER_DB
 #include "ha_ndbcluster.h"
 extern handlerton ndbcluster_hton;
+#else
+handlerton ndbcluster_hton = { "ndbcluster", SHOW_OPTION_NO,
+  "Clustered, fault-tolerant, memory-based tables", 
+  DB_TYPE_NDBCLUSTER, NULL, 0, 0, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #ifdef HAVE_FEDERATED_DB
 #include "ha_federated.h"
 extern handlerton federated_hton;
+#else
+handlerton federated_hton = { "FEDERATED", SHOW_OPTION_NO, 
+  "Federated MySQL storage engine", DB_TYPE_FEDERATED_DB, NULL, 0, 0, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  HTON_NO_FLAGS };
 #endif
 #include <myisampack.h>
 #include <errno.h>
@@ -65,13 +115,17 @@ extern handlerton myisammrg_hton;
 extern handlerton heap_hton;
 extern handlerton binlog_hton;
 
+/*
+  Obsolete
+*/
+handlerton isam_hton = { "ISAM", SHOW_OPTION_NO, "Obsolete storage engine", 
+  DB_TYPE_ISAM, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+  NULL, NULL, NULL, NULL, NULL, NULL, HTON_NO_FLAGS };
 
-	/* static functions defined in this file */
 
-static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
+/* static functions defined in this file */
 
-/* list of all available storage engines (of their handlertons) */
-handlerton *handlertons[MAX_HA]={0};
+static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
 
 /* number of entries in handlertons[] */
 ulong total_ha;
@@ -87,31 +141,17 @@ handlerton *sys_table_types[]=
 {
   &myisam_hton,
   &heap_hton,
-#ifdef HAVE_INNOBASE_DB
   &innobase_hton,
-#endif
-#ifdef HAVE_BERKELEY_DB
   &berkeley_hton,
-#endif
-#ifdef HAVE_BLACKHOLE_DB
   &blackhole_hton,
-#endif
-#ifdef HAVE_EXAMPLE_DB
   &example_hton,
-#endif
-#ifdef HAVE_ARCHIVE_DB
   &archive_hton,
-#endif
-#ifdef HAVE_CSV_DB
   &tina_hton,
-#endif
-#ifdef HAVE_NDBCLUSTER_DB
   &ndbcluster_hton,
-#endif
-#ifdef HAVE_FEDERATED_DB
   &federated_hton,
-#endif
   &myisammrg_hton,
+  &binlog_hton,
+  &isam_hton,
   NULL
 };
 
@@ -183,12 +223,12 @@ const char *ha_get_storage_engine(enum db_type db_type)
 
 bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
 {
-  show_table_type_st *types;
-  for (types= sys_table_types; types->type; types++)
+  handlerton **types;
+  for (types= sys_table_types; *types; types++)
   {
-    if (db_type == types->db_type)
+    if (db_type == (*types)->db_type)
     {
-      if (types->ht->flags & flag)
+      if ((*types)->flags & flag)
         return TRUE;
       else
         return FALSE;
@@ -409,7 +449,6 @@ static inline void ha_was_inited_ok(handlerton **ht)
 int ha_init()
 {
   int error= 0;
-  handlerton **ht= handlertons;
   handlerton **types;
   show_table_alias_st *table_alias;
   total_ha= savepoint_alloc_size= 0;
@@ -418,38 +457,16 @@ int ha_init()
     return 1;
 
   /*
-    This will go away soon.
+    We now initialize everything here.
   */
   for (types= sys_table_types; *types; types++)
   {
-    /*
-      FUTURE -
-      We need to collapse sys_table_types and handlertons variables into 
-      one variable.
-    */
-    *ht= *types;
-    ht++;
-    if ((*types)->init)
-    {
-      if (!(*types)->init())
-        ha_was_inited_ok(types); 
-    }
-  }
-
-  if (opt_bin_log)
-  {
-    if (0) // Should fail until binlog is a bit more se like
-    {
-      mysql_bin_log.close(LOG_CLOSE_INDEX);     // Never used
-      opt_bin_log= 0;                           // Never used
-      error= 1;                                 // Never used
-    }
+    if (!(*types)->init || !(*types)->init())
+      ha_was_inited_ok(types); 
     else
-    {
-      *types= &binlog_hton;
-      ha_was_inited_ok(types);
-    }
+      (*types)->state= SHOW_OPTION_DISABLED;
   }
+
   DBUG_ASSERT(total_ha < MAX_HA);
   /*
     Check if there is a transaction-capable storage engine besides the
@@ -521,9 +538,10 @@ void ha_drop_database(char* path)
 /* don't bother to rollback here, it's done already */
 void ha_close_connection(THD* thd)
 {
-  for (uint i=0; i < total_ha; i++)
-    if (thd->ha_data[i])
-      (*handlertons[i]->close_connection)(thd);
+  handlerton **types;
+  for (types= sys_table_types; *types; types++)
+    if (thd->ha_data[(*types)->slot])
+      (*types)->close_connection(thd);
 }
 
 /* ========================================================================
@@ -834,13 +852,13 @@ int ha_autocommit_or_rollback(THD *thd, int error)
 
 int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
 {
-  handlerton **ht= handlertons, **end_ht=ht+total_ha;
+  handlerton **types;
   int res= 1;
 
-  for ( ; ht < end_ht ; ht++)
-    if ((*ht)->recover)
+  for (types= sys_table_types; *types; types++)
+    if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
       res= res &&
-        (*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(xid);
+        (*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid);
   return res;
 }
 
@@ -919,7 +937,7 @@ static char* xid_to_str(char *buf, XID *xid)
 int ha_recover(HASH *commit_list)
 {
   int len, got, found_foreign_xids=0, found_my_xids=0;
-  handlerton **ht= handlertons, **end_ht=ht+total_ha;
+  handlerton **types;
   XID *list=0;
   bool dry_run=(commit_list==0 && tc_heuristic_recover==0);
   DBUG_ENTER("ha_recover");
@@ -955,14 +973,14 @@ int ha_recover(HASH *commit_list)
     DBUG_RETURN(1);
   }
 
-  for ( ; ht < end_ht ; ht++)
+  for (types= sys_table_types; *types; types++)
   {
-    if (!(*ht)->recover)
+    if ((*types)->state != SHOW_OPTION_YES || !(*types)->recover)
       continue;
-    while ((got=(*(*ht)->recover)(list, len)) > 0 )
+    while ((got=(*(*types)->recover)(list, len)) > 0 )
     {
       sql_print_information("Found %d prepared transaction(s) in %s",
-                            got, (*ht)->name);
+                            got, (*types)->name);
       for (int i=0; i < got; i ++)
       {
         my_xid x=list[i].get_my_xid();
@@ -990,7 +1008,7 @@ int ha_recover(HASH *commit_list)
           char buf[XIDDATASIZE*4+6]; // see xid_to_str
           sql_print_information("commit xid %s", xid_to_str(buf, list+i));
 #endif
-          (*(*ht)->commit_by_xid)(list+i);
+          (*(*types)->commit_by_xid)(list+i);
         }
         else
         {
@@ -998,7 +1016,7 @@ int ha_recover(HASH *commit_list)
           char buf[XIDDATASIZE*4+6]; // see xid_to_str
           sql_print_information("rollback xid %s", xid_to_str(buf, list+i));
 #endif
-          (*(*ht)->rollback_by_xid)(list+i);
+          (*(*types)->rollback_by_xid)(list+i);
         }
       }
       if (got < len)
diff --git a/sql/handler.h b/sql/handler.h
index 18c39de28e67b52cc17ae042a4b4fe5f64ffcf1e..81048c0730ed5b43ea7662689a4257046217c95e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -854,7 +854,6 @@ extern handlerton *sys_table_types[];
 extern const char *ha_row_type[];
 extern TYPELIB tx_isolation_typelib;
 extern TYPELIB myisam_stats_method_typelib;
-extern handlerton *handlertons[MAX_HA];
 extern ulong total_ha, total_ha_2pc;
 
 	/* Wrapper functions */