diff --git a/.bzrignore b/.bzrignore index 751b823f1ea..095c04b36ee 100644 --- a/.bzrignore +++ b/.bzrignore @@ -291,6 +291,7 @@ client/my_decimal.h client/my_user.c client/mysql client/mysql.cpp +client/mysql_upgrade client/mysqladmin client/mysqladmin.c client/mysqladmin.cpp @@ -321,6 +322,7 @@ cmd-line-utils/libedit/makelist comon.h comp_err/*.ds? comp_err/*.vcproj +compile config.cache config.guess config.h @@ -367,6 +369,9 @@ extra/resolve_stack_dump extra/resolveip extra/sql_state.h extra/tztime.cc +extra/yassl/taocrypt/benchmark/benchmark +extra/yassl/taocrypt/test/test +extra/yassl/testsuite/testsuite fcns.c fcns.h gdbinit @@ -549,6 +554,7 @@ libmysqld/spatial.cc libmysqld/sql_acl.cc libmysqld/sql_analyse.cc libmysqld/sql_base.cc +libmysqld/sql_builtin.cc libmysqld/sql_cache.cc libmysqld/sql_class.cc libmysqld/sql_command @@ -679,6 +685,7 @@ mysql-test/mysql-test-run.log mysql-test/mysql_test_run_new mysql-test/ndb/ndbcluster mysql-test/r/*.err +mysql-test/r/*.log mysql-test/r/*.out mysql-test/r/*.reject mysql-test/r/alter_table.err @@ -1174,6 +1181,7 @@ sql/share/gmon.out sql/share/mysql sql/share/norwegian-ny/errmsg.sys sql/share/norwegian/errmsg.sys +sql/sql_builtin.cc sql/sql_select.cc.orig sql/sql_yacc.cc sql/sql_yacc.h @@ -1747,6 +1755,10 @@ tools/mysqlmanager tools/mysqlmngd tools/mysqltestmanager tools/mysys_priv.h +unittest/examples/*.t +unittest/mysys/*.t +unittest/mytap/t/*.t +unittest/unit vi.h vio/*.ds? vio/*.vcproj @@ -1758,9 +1770,3 @@ vio/viotest-sslconnect.cpp vio/viotest.cpp zlib/*.ds? zlib/*.vcproj -mysql-test/r/*.log -client/mysql_upgrade -unittest/examples/*.t -unittest/mysys/*.t -unittest/mytap/t/*.t -unittest/unit diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 6c83fffa8fb..589e609beeb 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -147,18 +147,9 @@ static_link="$static_link --with-client-ldflags=-all-static" local_infile_configs="--enable-local-infile" -max_configs="--with-innodb --with-berkeley-db" -max_configs="$max_configs --with-archive-storage-engine" -max_configs="$max_configs --with-big-tables" -max_configs="$max_configs --with-blackhole-storage-engine" -max_configs="$max_configs --with-federated-storage-engine" -max_configs="$max_configs --with-csv-storage-engine" -max_configs="$max_configs --with-example-storage-engine" -max_configs="$max_configs --with-partition $SSL_LIBRARY" - -max_no_embedded_configs="$max_configs --with-ndbcluster" -max_no_ndb_configs="$max_configs --without-ndbcluster --with-embedded-server" -max_configs="$max_configs --with-ndbcluster --with-embedded-server" +max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max" +max_no_ndb_configs="$SSL_LIBRARY --with-plugins=max-no-ndb --with-embedded-server" +max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server" # # CPU and platform specific compilation flags. diff --git a/Makefile.am b/Makefile.am index dbf43151d60..8709fca34c3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,12 +24,11 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common \ @thread_dirs@ pstack \ - @sql_union_dirs@ storage \ + @sql_union_dirs@ storage plugin \ @sql_server@ scripts @man_dirs@ tests \ - @mysql_se_plugins@ \ netware @libmysqld_dirs@ \ mysql-test support-files @tools_dirs@ \ - plugin unittest win + unittest win DIST_SUBDIRS = $(SUBDIRS) BUILD diff --git a/VC++Files/client/mysql_upgrade.dsp b/VC++Files/client/mysql_upgrade.dsp index a039098d639..28eb2a58f39 100644 --- a/VC++Files/client/mysql_upgrade.dsp +++ b/VC++Files/client/mysql_upgrade.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=mysql_upgrade - Win32 Release +CFG=mysql_upgrade - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,59 +13,112 @@ CFG=mysql_upgrade - Win32 Release !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "mysql_upgrade.mak" CFG="mysql_upgrade - Win32 Release" +!MESSAGE NMAKE /f "mysql_upgrade.mak" CFG="mysql_upgrade - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "mysql_upgrade - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mysql_upgrade - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "mysql_upgrade - Win32 classic" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=cl.exe +CPP=xicl6.exe RSC=rc.exe + +!IF "$(CFG)" == "mysql_upgrade - Win32 Release" + # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "mysql_upgrade___Win32_Release" -# PROP BASE Intermediate_Dir "mysql_upgrade___Win32_Release" +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "mysql_upgrade___Win32_Release" -# PROP Intermediate_Dir "mysql_upgrade___Win32_Release" +# PROP Output_Dir "release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /D "NDEBUG" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /Fp"Release/mysql_upgrade.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c -# ADD BASE RSC /l 0x416 /d "NDEBUG" -# ADD RSC /l 0x416 /d "NDEBUG" +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /pdb:"release/mysql_upgrade.pdb" /machine:I386 /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" -# SUBTRACT LINK32 /pdb:none +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib ..\extra\yassl\Release\yassl.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" +# SUBTRACT LINK32 /incremental:yes + +!ELSEIF "$(CFG)" == "mysql_upgrade - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "mysqlimp" +# PROP BASE Intermediate_Dir "mysqlimp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /G6 /MTd /W3 /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib setargv.obj ..\extra\yassl\Debug\yassl.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysql_upgrade.exe" /pdbtype:sept /libpath:"..\lib_debug\\" + +!ELSEIF "$(CFG)" == "mysql_upgrade - Win32 classic" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "mysql_upgrade___Win32_classic" +# PROP BASE Intermediate_Dir "mysql_upgrade___Win32_classic" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "classic" +# PROP Intermediate_Dir "classic" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "_CONSOLE" /D "_WINDOWS" /D LICENSE=Commercial /D "DBUG_OFF" /D "_MBCS" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" +# SUBTRACT BASE LINK32 /incremental:yes +# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib ..\extra\yassl\Release\yassl.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysql_upgrade.exe" /libpath:"..\lib_release\\" +# SUBTRACT LINK32 /incremental:yes + +!ENDIF + # Begin Target # Name "mysql_upgrade - Win32 Release" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Name "mysql_upgrade - Win32 Debug" +# Name "mysql_upgrade - Win32 classic" # Begin Source File SOURCE=.\mysql_upgrade.c # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/VC++Files/client/mysql_upgrade.vcproj b/VC++Files/client/mysql_upgrade.vcproj new file mode 100644 index 00000000000..38cae600a75 --- /dev/null +++ b/VC++Files/client/mysql_upgrade.vcproj @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VC++Files/client/mysql_upgrade_ia64.dsp b/VC++Files/client/mysql_upgrade_ia64.dsp index a116f3f06c3..5cb42ba0224 100644 --- a/VC++Files/client/mysql_upgrade_ia64.dsp +++ b/VC++Files/client/mysql_upgrade_ia64.dsp @@ -4,21 +4,23 @@ # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=mysql_upgrade - Win32 Release +CFG=mysql_upgrade - WinIA64 classic !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mysql_upgrade.mak". -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "mysql_upgrade_ia64.mak". +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mysql_upgrade.mak" CFG="mysql_upgrade - Win32 Release" -!MESSAGE +!MESSAGE +!MESSAGE NMAKE /f "mysql_upgrade_ia64.mak" CFG="mysql_upgrade - WinIA64 classic" +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "mysql_upgrade - WinIA64 Release" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE "mysql_upgrade - WinIA64 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "mysql_upgrade - WinIA64 classic" (based on "Win32 (x86) Console Application") +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -27,51 +29,96 @@ CFG=mysql_upgrade - Win32 Release CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "mysql - WinIA64 Release" +!IF "$(CFG)" == "mysql_upgrade - WinIA64 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "mysql_upgrade___WinIA64_Release" -# PROP BASE Intermediate_Dir "mysql_upgrade___WinIA64_Release" +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "mysql_upgrade___WinIA64_Release" -# PROP Intermediate_Dir "mysql_upgrade___WinIA64_Release" +# PROP Output_Dir "release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" +MTL=midl.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN64" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /I "../include" /D"NDEBUG" /D"DBUG_OFF" /D"_CONSOLE" /D"_MBCS" /D"_WINDOWS" /Fp"Release/mysql_upgrade.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c /O2 /G2 /EHsc /D"_IA64_" /Zi /D"WIN64" /D"WIN32" /D"_AFX_NO_DAO_SUPPORT" /Wp64 /Zm600 -# ADD BASE RSC /l 0x416 /d "NDEBUG" -# ADD RSC /l 0x416 /d "NDEBUG" +# ADD CPP /nologo /MT /W3 /Zi /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "NDEBUG" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /FD /G2 /EHsc /Wp64 /Zm600 /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /pdb:"release/mysql_upgrade.pdb" /machine:IA64 /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" /incremental:no -# SUBTRACT LINK32 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:IA64 +# ADD LINK32 ..\lib_release\zlib.lib mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib bufferoverflowU.lib zlib.lib /nologo /subsystem:console /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" /machine:IA64 -!ENDIF +!ELSEIF "$(CFG)" == "mysql_upgrade - WinIA64 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "mysqlimp" +# PROP BASE Intermediate_Dir "mysqlimp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "debug" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN64" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "SAFEMALLOC" /D "SAFE_MUTEX" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /FD /G2 /EHsc /Wp64 /Zm600 /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:IA64 +# ADD LINK32 setargv.obj ..\lib_debug\zlib.lib ..\lib_debug\dbug.lib mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib bufferoverflowU.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /out:"../client_debug/mysql_upgrade.exe" /libpath:"..\lib_debug\\" /machine:IA64 + +!ELSEIF "$(CFG)" == "mysql_upgrade - WinIA64 classic" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "mysql_upgrade___WinIA64_classic" +# PROP BASE Intermediate_Dir "mysql_upgrade___WinIA64_classic" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "classic" +# PROP Intermediate_Dir "classic" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE CPP /nologo /G6 /MT /W3 /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_CONSOLE" /D "_MBCS" /D "_WINDOWS" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MT /W3 /Zi /O2 /I "../include" /I "../" /D "_CONSOLE" /D "_WINDOWS" /D LICENSE=Commercial /D "DBUG_OFF" /D "_MBCS" /D "NDEBUG" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /FD /G2 /EHsc /Wp64 /Zm600 /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /out:"../client_release/mysql_upgrade.exe" /libpath:"..\lib_release\\" /machine:IA64 +# ADD LINK32 ..\lib_release\zlib.lib mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib bufferoverflowU.lib zlib.lib /nologo /subsystem:console /out:"../client_classic/mysql_upgrade.exe" /libpath:"..\lib_release\\" /machine:IA64 + +!ENDIF # Begin Target # Name "mysql_upgrade - WinIA64 Release" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Name "mysql_upgrade - WinIA64 Debug" +# Name "mysql_upgrade - WinIA64 classic" # Begin Source File SOURCE=.\mysql_upgrade.c # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/VC++Files/libmysqld/libmysqld.dsp b/VC++Files/libmysqld/libmysqld.dsp index 9c4485210a6..1c80147a8f5 100644 --- a/VC++Files/libmysqld/libmysqld.dsp +++ b/VC++Files/libmysqld/libmysqld.dsp @@ -363,6 +363,10 @@ SOURCE=..\mysys\my_getopt.c SOURCE=..\sql-common\my_time.c # End Source File # Begin Source File + +SOURCE=..\sql-common\my_user.c +# End Source File +# Begin Source File SOURCE=..\sql\net_serv.cpp # End Source File diff --git a/VC++Files/libmysqld/libmysqld_ia64.dsp b/VC++Files/libmysqld/libmysqld_ia64.dsp index b5223e38f2d..9668193fc1d 100644 --- a/VC++Files/libmysqld/libmysqld_ia64.dsp +++ b/VC++Files/libmysqld/libmysqld_ia64.dsp @@ -338,6 +338,10 @@ SOURCE="..\sql-common\my_time.c" # End Source File # Begin Source File +SOURCE="..\sql-common\my_user.c" +# End Source File +# Begin Source File + SOURCE=..\sql\net_serv.cpp # End Source File # Begin Source File diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw index dd70ad630a1..a5f5a214bd6 100644 --- a/VC++Files/mysql.dsw +++ b/VC++Files/mysql.dsw @@ -446,6 +446,9 @@ Package=<4> Project_Dep_Name mysqlimport End Project Dependency Begin Project Dependency + Project_Dep_Name mysql_upgrade + End Project Dependency + Begin Project Dependency Project_Dep_Name mysqlshow End Project Dependency Begin Project Dependency @@ -530,6 +533,24 @@ Package=<4> ############################################################################### +Project: "mysql_upgrade"=".\client\mysql_upgade.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name mysqlclient + End Project Dependency + Begin Project Dependency + Project_Dep_Name mysys + End Project Dependency +}}} + +############################################################################### + Project: "mysqlserver"=".\mysqlserver\mysqlserver.dsp" - Package Owner=<4> Package=<5> diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln index 344aaa38507..c5bf8291888 100644 --- a/VC++Files/mysql.sln +++ b/VC++Files/mysql.sln @@ -157,6 +157,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlimport", "client\mysql {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_upgrade", "client\mysql_upgrade.vcproj", "{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}" + ProjectSection(ProjectDependencies) = postProject + {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} + {26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB} + {8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF} + {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlserver", "mysqlserver\mysqlserver.vcproj", "{94B86159-C581-42CD-825D-C69CBC237E5C}" ProjectSection(ProjectDependencies) = postProject {EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859} @@ -249,6 +257,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\mysql_client_test.vcproj", "{DA224DAB-5006-42BE-BB77-16E8BE5326D5}" ProjectSection(ProjectDependencies) = postProject {26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB} + {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tools\instance-manager\mysqlmanager.vcproj", "{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}" diff --git a/VC++Files/mysql_ia64.dsw b/VC++Files/mysql_ia64.dsw index 96878cd3651..0f9c5471f7e 100644 --- a/VC++Files/mysql_ia64.dsw +++ b/VC++Files/mysql_ia64.dsw @@ -528,6 +528,9 @@ Package=<4> Project_Dep_Name mysqlimport End Project Dependency Begin Project Dependency + Project_Dep_Name mysql_upgrade + End Project Dependency + Begin Project Dependency Project_Dep_Name mysqlshow End Project Dependency Begin Project Dependency @@ -600,6 +603,21 @@ Package=<4> ############################################################################### +Project: "mysql_upgrade"=".\client\mysql_upgrade_ia64.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name mysqlclient + End Project Dependency +}}} + +############################################################################### + Project: "mysqlserver"=".\mysqlserver\mysqlserver_ia64.dsp" - Package Owner=<4> Package=<5> diff --git a/VC++Files/mysys/mysys.vcproj b/VC++Files/mysys/mysys.vcproj index befb4ad58b0..cf367e5666b 100644 --- a/VC++Files/mysys/mysys.vcproj +++ b/VC++Files/mysys/mysys.vcproj @@ -3232,6 +3232,49 @@ PreprocessorDefinitions=""/> + + + + + + + + + + + + + + + + + ptr(),buffer->length()); #ifdef HAVE_READLINE @@ -1981,6 +2011,7 @@ com_go(String *buffer,char *line __attribute__((unused))) if (error) { + executing_query= 0; buffer->length(0); // Remove query on error return error; } @@ -1992,13 +2023,19 @@ com_go(String *buffer,char *line __attribute__((unused))) if (quick) { if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql)) - return put_error(&mysql); + { + executing_query= 0; + return put_error(&mysql); + } } else { error= mysql_store_result_for_lazy(&result); if (error) - return error; + { + executing_query= 0; + return error; + } } if (verbose >= 3 || !opt_silent) @@ -2073,6 +2110,7 @@ com_go(String *buffer,char *line __attribute__((unused))) (mysql.server_status & SERVER_STATUS_DB_DROPPED)) get_current_db(); + executing_query= 0; return error; /* New command follows */ } @@ -2286,6 +2324,8 @@ print_table_data(MYSQL_RES *result) while ((cur= mysql_fetch_row(result))) { + if (interrupted_query) + break; ulong *lengths= mysql_fetch_lengths(result); (void) tee_fputs("| ", PAGER); mysql_field_seek(result, 0); @@ -2393,6 +2433,8 @@ print_table_data_html(MYSQL_RES *result) } while ((cur = mysql_fetch_row(result))) { + if (interrupted_query) + break; ulong *lengths=mysql_fetch_lengths(result); (void) tee_fputs("", PAGER); for (uint i=0; i < mysql_num_fields(result); i++) @@ -2422,6 +2464,8 @@ print_table_data_xml(MYSQL_RES *result) fields = mysql_fetch_fields(result); while ((cur = mysql_fetch_row(result))) { + if (interrupted_query) + break; ulong *lengths=mysql_fetch_lengths(result); (void) tee_fputs("\n \n", PAGER); for (uint i=0; i < mysql_num_fields(result); i++) @@ -2456,6 +2500,8 @@ print_table_data_vertically(MYSQL_RES *result) mysql_field_seek(result,0); for (uint row_count=1; (cur= mysql_fetch_row(result)); row_count++) { + if (interrupted_query) + break; mysql_field_seek(result,0); tee_fprintf(PAGER, "*************************** %d. row ***************************\n", row_count); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 78e4acd4c1d..3288b627554 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -135,7 +135,9 @@ static int create_check_file(const char *path) if (check_file < 0) return 1; - error= my_write(check_file, VERSION, strlen(VERSION), MYF(MY_WME | MY_FNABP)); + error= my_write(check_file, + MYSQL_SERVER_VERSION, strlen(MYSQL_SERVER_VERSION), + MYF(MY_WME | MY_FNABP)); error= my_close(check_file, MYF(MY_FAE | MY_WME)) || error; return error; } @@ -243,7 +245,7 @@ int main(int argc, char **argv) && (test_file_exists("./bin", "mysqld") || test_file_exists("./libexec", "mysqld"))) { - getcwd(bindir, sizeof(bindir)); + my_getwd(bindir, sizeof(bindir), MYF(0)); bindir_end= bindir + strlen(bindir); } else @@ -305,7 +307,7 @@ int main(int argc, char **argv) b_read= my_read(check_file, chf_buffer, sizeof(chf_buffer)-1, MYF(0)); chf_buffer[b_read]= 0; my_close(check_file, MYF(0)); - if (!strcmp(chf_buffer, VERSION)) + if (!strcmp(chf_buffer, MYSQL_SERVER_VERSION)) { if (opt_verbose) puts("mysql_upgrade already done for this version"); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index d9b4230348e..11d3ae5a2df 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -457,8 +457,8 @@ static struct my_option my_long_options[] = (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, {"preserve-schema", OPT_MYSQL_PRESERVE_SCHEMA, - "Preserve the schema from the mysqlslap run, this happens unless \ - --auto-generate-sql or --create are used.", + "Preserve the schema from the mysqlslap run, this happens unless " + "--auto-generate-sql or --create are used.", (gptr*) &opt_preserve, (gptr*) &opt_preserve, 0, GET_BOOL, NO_ARG, TRUE, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, diff --git a/client/mysqltest.c b/client/mysqltest.c index cfd69e45ba7..ce876708fbc 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -153,7 +153,7 @@ static uint global_expected_errors; /* ************************************************************************ */ -static int record = 0, opt_sleep=0; +static int record= 0, opt_sleep= -1; static char *db = 0, *pass=0; const char *user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; const char *opt_include= 0; @@ -688,10 +688,11 @@ static void die(const char *fmt, ...) /* Note that we will get some memory leaks when calling this! */ -static void abort_not_supported_test() +static void abort_not_supported_test(const char *fname) { DBUG_ENTER("abort_not_supported_test"); - fprintf(stderr, "This test is not supported by this installation\n"); + fprintf(stderr, "The test '%s' is not supported by this installation\n", + fname); if (!silent) printf("skipped\n"); free_used_memory(); @@ -814,7 +815,7 @@ static void check_result(DYNAMIC_STRING* ds, const char *fname, DBUG_ENTER("check_result"); if (res && require_option) - abort_not_supported_test(); + abort_not_supported_test(fname); switch (res) { case RESULT_OK: break; /* ok */ @@ -1036,7 +1037,7 @@ int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) int do_require_manager(struct st_query *query __attribute__((unused)) ) { if (!manager) - abort_not_supported_test(); + abort_not_supported_test("manager"); return 0; } @@ -1305,7 +1306,9 @@ int var_query_set(VAR* var, const char *query, const char** query_end) uint i; ulong *lengths; char *end; +#ifdef NOT_YET MYSQL_FIELD *fields= mysql_fetch_fields(res); +#endif init_dynamic_string(&result, "", 16384, 65536); lengths= mysql_fetch_lengths(res); @@ -1880,11 +1883,12 @@ int do_sleep(struct st_query *query, my_bool real_sleep) query->first_argument); /* Fixed sleep time selected by --sleep option */ - if (opt_sleep && !real_sleep) + if (opt_sleep >= 0 && !real_sleep) sleep_val= opt_sleep; DBUG_PRINT("info", ("sleep_val: %f", sleep_val)); - my_sleep((ulong) (sleep_val * 1000000L)); + if (sleep_val) + my_sleep((ulong) (sleep_val * 1000000L)); query->last_argument= sleep_end; return 0; } @@ -1919,7 +1923,7 @@ static void set_charset(struct st_query *q) q->last_argument= p; charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); if (!charset_info) - abort_not_supported_test(); + abort_not_supported_test(charset_name); } static uint get_errcodes(match_err *to,struct st_query *q) @@ -1956,7 +1960,13 @@ static uint get_errcodes(match_err *to,struct st_query *q) ; for (; e->name; e++) { - if (!strncmp(start, e->name, (int) (p - start))) + /* + If we get a match, we need to check the length of the name we + matched against in case it was longer than what we are checking + (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT). + */ + if (!strncmp(start, e->name, (int) (p - start)) && + (uint) strlen(e->name) == (uint) (p - start)) { to[count].code.errnum= (uint) e->code; to[count].type= ERR_ERRNO; @@ -3304,7 +3314,7 @@ static struct my_option my_long_options[] = "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"sleep", 'T', "Sleep always this many seconds on sleep commands.", - (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, + (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, @@ -4322,7 +4332,7 @@ static void handle_error(const char *query, struct st_query *q, if (err_errno == CR_SERVER_LOST || err_errno == CR_SERVER_GONE_ERROR) die("require query '%s' failed: %d: %s", query, err_errno, err_error); - abort_not_supported_test(); + abort_not_supported_test("failed_query"); } if (q->abort_on_error) @@ -5094,7 +5104,7 @@ static void init_var_hash(MYSQL *mysql) DBUG_VOID_RETURN; } -static void mark_progress(int line) +static void mark_progress(int line __attribute__((unused))) { #ifdef NOT_YET static FILE* fp = NULL; diff --git a/cmakelists.txt b/cmakelists.txt index 0e91f49be90..5edc33b9f5a 100644 --- a/cmakelists.txt +++ b/cmakelists.txt @@ -9,56 +9,53 @@ SET(WITH_CSV_STORAGE_ENGINE TRUE) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in ${CMAKE_SOURCE_DIR}/include/mysql_version.h @ONLY) +SET(WITH_HEAP_STORAGE_ENGINE TRUE) +ADD_DEFINITIONS(-D WITH_HEAP_STORAGE_ENGINE) +SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_heap_plugin") + +SET(WITH_MYISAM_STORAGE_ENGINE TRUE) +ADD_DEFINITIONS(-D WITH_MYISAM_STORAGE_ENGINE) +SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisam_plugin") + +SET(WITH_MYISAMMRG_STORAGE_ENGINE TRUE) +ADD_DEFINITIONS(-D WITH_MYISAMMRG_STORAGE_ENGINE) +SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisammrg_plugin") + IF(WITH_ARCHIVE_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_ARCHIVE_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &archive_hton") - SET (mysql_se_decls "${mysql_se_decls}, archive_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_archive.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_archive_plugin") ENDIF(WITH_ARCHIVE_STORAGE_ENGINE) IF(WITH_BLACKHOLE_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_BLACKHOLE_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &blackhole_hton") - SET (mysql_se_decls "${mysql_se_decls}, blackhole_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_blackhole.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_blackhole_plugin") ENDIF(WITH_BLACKHOLE_STORAGE_ENGINE) IF(WITH_CSV_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_CSV_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &tina_hton") - SET (mysql_se_decls "${mysql_se_decls}, tina_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../storage/csv/ha_tina.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_csv_plugin") ENDIF(WITH_CSV_STORAGE_ENGINE) IF(WITH_EXAMPLE_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_EXAMPLE_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &example_hton") - SET (mysql_se_decls "${mysql_se_decls}, example_hton") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_example_plugin") ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) IF(WITH_INNOBASE_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_INNOBASE_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &innobase_hton") - SET (mysql_se_decls "${mysql_se_decls}, innobase_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_innodb.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_innobase_plugin") ENDIF(WITH_INNOBASE_STORAGE_ENGINE) IF(WITH_PARTITION_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_PARTITION_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &partition_hton") - SET (mysql_se_decls "${mysql_se_decls}, partition_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_partition.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_partition_plugin") ENDIF(WITH_PARTITION_STORAGE_ENGINE) IF(WITH_FEDERATED_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_FEDERATED_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &federated_hton") - SET (mysql_se_decls "${mysql_se_decls}, federated_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_federated.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_federated_plugin") ENDIF(WITH_FEDERATED_STORAGE_ENGINE) IF(WITH_BERKELEY_STORAGE_ENGINE) ADD_DEFINITIONS(-D WITH_BERKELEY_STORAGE_ENGINE) - SET (mysql_se_htons "${mysql_se_htons}, &berkeley_hton") - SET (mysql_se_decls "${mysql_se_decls}, berkeley_hton") - SET (mysql_se_ha_src ${mysql_se_ha_src} "../sql/ha_berkeley.cc") + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_berkeley_plugin") ENDIF(WITH_BERKELEY_STORAGE_ENGINE) -CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/handlerton.cc.in - ${CMAKE_SOURCE_DIR}/sql/handlerton.cc @ONLY) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc.in + ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc @ONLY) SET(localstatedir "C:\\mysql\\data") CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-huge.cnf.sh @@ -137,6 +134,12 @@ ENDIF(WITH_ARCHIVE_STORAGE_ENGINE) IF(WITH_BERKELEY_STORAGE_ENGINE) ADD_SUBDIRECTORY(storage/bdb) ENDIF(WITH_BERKELEY_STORAGE_ENGINE) +IF(WITH_BLACKHOLE_STORAGE_ENGINE) + ADD_SUBDIRECTORY(storage/blackhole) +ENDIF(WITH_BLACKHOLE_STORAGE_ENGINE) +IF(WITH_CSV_STORAGE_ENGINE) + ADD_SUBDIRECTORY(storage/csv) +ENDIF(WITH_CSV_STORAGE_ENGINE) IF(WITH_EXAMPLE_STORAGE_ENGINE) ADD_SUBDIRECTORY(storage/example) ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) diff --git a/config/ac-macros/ha_archive.m4 b/config/ac-macros/ha_archive.m4 deleted file mode 100644 index 2d2558ea600..00000000000 --- a/config/ac-macros/ha_archive.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_ARCHIVEDB -dnl Sets HAVE_ARCHIVE_DB if --with-archive-storage-engine is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_ARCHIVEDB], [ - AC_ARG_WITH([archive-storage-engine], - [ - --with-archive-storage-engine - Enable the Archive Storage Engine], - [archivedb="$withval"], - [archivedb=no]) - AC_MSG_CHECKING([for archive storage engine]) - - case "$archivedb" in - yes ) - AC_DEFINE([HAVE_ARCHIVE_DB], [1], [Builds Archive Storage Engine]) - AC_MSG_RESULT([yes]) - [archivedb=yes] - ;; - * ) - AC_MSG_RESULT([no]) - [archivedb=no] - ;; - esac - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_ARCHIVE SECTION -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/ha_berkeley.m4 b/config/ac-macros/ha_berkeley.m4 index 183a622dfc9..c7d99bd8e03 100644 --- a/config/ac-macros/ha_berkeley.m4 +++ b/config/ac-macros/ha_berkeley.m4 @@ -8,23 +8,20 @@ dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_SETUP_BERKELEY_DB], [ AC_ARG_WITH([berkeley-db], - [ - --with-berkeley-db[=DIR] - Use BerkeleyDB located in DIR], + AS_HELP_STRING([--with-berkeley-db[[[[[=DIR]]]]]], + [Use BerkeleyDB located in DIR]), [bdb="$withval"], [bdb=yes]) AC_ARG_WITH([berkeley-db-includes], - [ - --with-berkeley-db-includes=DIR - Find Berkeley DB headers in DIR], + AS_HELP_STRING([--with-berkeley-db-includes=DIR], + [Find Berkeley DB headers in DIR]), [bdb_includes="$withval"], [bdb_includes=default]) AC_ARG_WITH([berkeley-db-libs], - [ - --with-berkeley-db-libs=DIR - Find Berkeley DB libraries in DIR], + AS_HELP_STRING([--with-berkeley-db-libs=DIR], + [Find Berkeley DB libraries in DIR]), [bdb_libs="$withval"], [bdb_libs=default]) @@ -120,12 +117,9 @@ AC_DEFUN([MYSQL_SETUP_BERKELEY_DB], [ sh $rel_srcdir/$bdb/dist/configure $bdb_conf_flags) || \ AC_MSG_ERROR([could not configure Berkeley DB]) - mysql_se_libs="$mysql_se_libs $bdb_libs_with_path" - AC_SUBST(bdb_includes) AC_SUBST(bdb_libs) AC_SUBST(bdb_libs_with_path) - AC_CONFIG_FILES(storage/bdb/Makefile) ]) AC_DEFUN([MYSQL_CHECK_INSTALLED_BDB], [ diff --git a/config/ac-macros/ha_blackhole.m4 b/config/ac-macros/ha_blackhole.m4 deleted file mode 100644 index cc4d360f5a8..00000000000 --- a/config/ac-macros/ha_blackhole.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_BLACKHOLEDB -dnl Sets HAVE_BLACKHOLE_DB if --with-blackhole-storage-engine is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_BLACKHOLEDB], [ - AC_ARG_WITH([blackhole-storage-engine], - [ - --with-blackhole-storage-engine - Enable the Blackhole Storage Engine], - [blackholedb="$withval"], - [blackholedb=no]) - AC_MSG_CHECKING([for blackhole storage engine]) - - case "$blackholedb" in - yes ) - AC_DEFINE([HAVE_BLACKHOLE_DB], [1], [Builds Blackhole Storage Engine]) - AC_MSG_RESULT([yes]) - [blackholedb=yes] - ;; - * ) - AC_MSG_RESULT([no]) - [blackholedb=no] - ;; - esac - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_BLACKHOLE SECTION -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/ha_example.m4 b/config/ac-macros/ha_example.m4 deleted file mode 100644 index f8067931ce6..00000000000 --- a/config/ac-macros/ha_example.m4 +++ /dev/null @@ -1,30 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_EXAMPLEDB -dnl Sets HAVE_EXAMPLE_DB if --with-example-storage-engine is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_EXAMPLEDB], [ - AC_ARG_WITH([example-storage-engine], - [ - --with-example-storage-engine - Enable the Example Storage Engine], - [exampledb="$withval"], - [exampledb=no]) - AC_MSG_CHECKING([for example storage engine]) - - case "$exampledb" in - yes ) - AC_DEFINE([HAVE_EXAMPLE_DB], [1], [Builds Example DB]) - AC_MSG_RESULT([yes]) - [exampledb=yes] - ;; - * ) - AC_MSG_RESULT([no]) - [exampledb=no] - ;; - esac - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_EXAMPLE SECTION -dnl --------------------------------------------------------------------------- - diff --git a/config/ac-macros/ha_federated.m4 b/config/ac-macros/ha_federated.m4 deleted file mode 100644 index 5c991f31666..00000000000 --- a/config/ac-macros/ha_federated.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_FEDERATED -dnl Sets HAVE_FEDERATED if --with-federated-storage-engine is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_FEDERATED], [ - AC_ARG_WITH([federated-storage-engine], - [ - --with-federated-storage-engine - Enable the MySQL Federated Storage Engine], - [federateddb="$withval"], - [federateddb=no]) - AC_MSG_CHECKING([for MySQL federated storage engine]) - - case "$federateddb" in - yes ) - AC_DEFINE([HAVE_FEDERATED_DB], [1], [Define to enable Federated Handler]) - AC_MSG_RESULT([yes]) - [federateddb=yes] - ;; - * ) - AC_MSG_RESULT([no]) - [federateddb=no] - ;; - esac - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_FEDERATED SECTION -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/ha_innodb.m4 b/config/ac-macros/ha_innodb.m4 deleted file mode 100644 index 287b77c8851..00000000000 --- a/config/ac-macros/ha_innodb.m4 +++ /dev/null @@ -1,77 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_INNODB -dnl Sets HAVE_INNOBASE_DB if --with-innodb is used -dnl --------------------------------------------------------------------------- - -AC_DEFUN([MYSQL_CHECK_INNODB], [ - AC_ARG_WITH([innodb], - [ - --without-innodb Do not include the InnoDB table handler], - [innodb="$withval"], - [innodb=yes]) - - AC_MSG_CHECKING([for Innodb]) - - have_innodb=no - innodb_includes= - innodb_libs= - case "$innodb" in - yes ) - AC_MSG_RESULT([Using Innodb]) - AC_DEFINE([HAVE_INNOBASE_DB], [1], [Using Innobase DB]) - have_innodb="yes" - innodb_includes="-I\$(top_builddir)/innobase/include" - innodb_system_libs="" -dnl Some libs are listed several times, in order for gcc to sort out -dnl circular references. - innodb_libs="\ - \$(top_builddir)/storage/innobase/usr/libusr.a\ - \$(top_builddir)/storage/innobase/srv/libsrv.a\ - \$(top_builddir)/storage/innobase/dict/libdict.a\ - \$(top_builddir)/storage/innobase/que/libque.a\ - \$(top_builddir)/storage/innobase/srv/libsrv.a\ - \$(top_builddir)/storage/innobase/ibuf/libibuf.a\ - \$(top_builddir)/storage/innobase/row/librow.a\ - \$(top_builddir)/storage/innobase/pars/libpars.a\ - \$(top_builddir)/storage/innobase/btr/libbtr.a\ - \$(top_builddir)/storage/innobase/trx/libtrx.a\ - \$(top_builddir)/storage/innobase/read/libread.a\ - \$(top_builddir)/storage/innobase/usr/libusr.a\ - \$(top_builddir)/storage/innobase/buf/libbuf.a\ - \$(top_builddir)/storage/innobase/ibuf/libibuf.a\ - \$(top_builddir)/storage/innobase/eval/libeval.a\ - \$(top_builddir)/storage/innobase/log/liblog.a\ - \$(top_builddir)/storage/innobase/fsp/libfsp.a\ - \$(top_builddir)/storage/innobase/fut/libfut.a\ - \$(top_builddir)/storage/innobase/fil/libfil.a\ - \$(top_builddir)/storage/innobase/lock/liblock.a\ - \$(top_builddir)/storage/innobase/mtr/libmtr.a\ - \$(top_builddir)/storage/innobase/page/libpage.a\ - \$(top_builddir)/storage/innobase/rem/librem.a\ - \$(top_builddir)/storage/innobase/thr/libthr.a\ - \$(top_builddir)/storage/innobase/sync/libsync.a\ - \$(top_builddir)/storage/innobase/data/libdata.a\ - \$(top_builddir)/storage/innobase/mach/libmach.a\ - \$(top_builddir)/storage/innobase/ha/libha.a\ - \$(top_builddir)/storage/innobase/dyn/libdyn.a\ - \$(top_builddir)/storage/innobase/mem/libmem.a\ - \$(top_builddir)/storage/innobase/sync/libsync.a\ - \$(top_builddir)/storage/innobase/ut/libut.a\ - \$(top_builddir)/storage/innobase/os/libos.a\ - \$(top_builddir)/storage/innobase/ut/libut.a" - - AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) - ;; - * ) - AC_MSG_RESULT([Not using Innodb]) - ;; - esac - - AC_SUBST(innodb_includes) - AC_SUBST(innodb_libs) - AC_SUBST(innodb_system_libs) -]) - -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_INNODB SECTION -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/ha_ndbcluster.m4 b/config/ac-macros/ha_ndbcluster.m4 index 8e839d8fee9..aee445f8d58 100644 --- a/config/ac-macros/ha_ndbcluster.m4 +++ b/config/ac-macros/ha_ndbcluster.m4 @@ -191,7 +191,6 @@ AC_DEFUN([MYSQL_SETUP_NDBCLUSTER], [ ndbcluster_libs="\$(top_builddir)/storage/ndb/src/.libs/libndbclient.a" ndbcluster_system_libs="" ndb_mgmclient_libs="\$(top_builddir)/storage/ndb/src/mgmclient/libndbmgmclient.la" - mysql_se_objs="$mysql_se_objs ha_ndbcluster_binlog.o" MYSQL_CHECK_NDB_OPTIONS NDBCLUSTER_WORKAROUNDS @@ -282,9 +281,6 @@ AC_DEFUN([MYSQL_SETUP_NDBCLUSTER], [ ndb_bin_am_ldflags="" fi - mysql_se_libs="$mysql_se_libs $ndbcluster_libs $ndbcluster_system_libs" - mysql_se_libs="$mysql_se_libs $NDB_SCI_LIBS" - AC_SUBST(NDB_VERSION_MAJOR) AC_SUBST(NDB_VERSION_MINOR) AC_SUBST(NDB_VERSION_BUILD) @@ -302,6 +298,7 @@ AC_DEFUN([MYSQL_SETUP_NDBCLUSTER], [ AC_SUBST(ndbcluster_libs) AC_SUBST(ndbcluster_system_libs) AC_SUBST(ndb_mgmclient_libs) + AC_SUBST(NDB_SCI_LIBS) AC_SUBST(ndb_transporter_opt_objs) AC_SUBST(ndb_port) @@ -311,7 +308,7 @@ AC_DEFUN([MYSQL_SETUP_NDBCLUSTER], [ AC_SUBST(NDB_DEFS) AC_SUBST(ndb_cxxflags_fix) - AC_CONFIG_FILES(storage/ndb/Makefile storage/ndb/include/Makefile dnl + AC_CONFIG_FILES(storage/ndb/include/Makefile dnl storage/ndb/src/Makefile storage/ndb/src/common/Makefile dnl storage/ndb/docs/Makefile dnl storage/ndb/tools/Makefile dnl diff --git a/config/ac-macros/ha_partition.m4 b/config/ac-macros/ha_partition.m4 deleted file mode 100644 index 1ce7dedc5f3..00000000000 --- a/config/ac-macros/ha_partition.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_PARTITIONDB -dnl Sets HAVE_PARTITION_DB if --with-partition is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_PARTITIONDB], [ - AC_ARG_WITH([partition], - [ - --with-partition - Enable the Partition Storage Engine], - [partitiondb="$withval"], - [partitiondb=no]) - AC_MSG_CHECKING([for partition]) - -dnl case "$partitiondb" in -dnl yes ) -dnl AC_DEFINE([HAVE_PARTITION_DB], [1], [Builds Partition DB]) -dnl AC_MSG_RESULT([yes]) -dnl [partitiondb=yes] -dnl ;; -dnl * ) -dnl AC_MSG_RESULT([no]) -dnl [partitiondb=no] -dnl ;; -dnl esac - AC_DEFINE([HAVE_PARTITION_DB], [1], [Builds Partition DB]) - AC_MSG_RESULT([yes]) - [partitiondb=yes] - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_PARTITION SECTION -dnl --------------------------------------------------------------------------- - diff --git a/config/ac-macros/ha_tina.m4 b/config/ac-macros/ha_tina.m4 deleted file mode 100644 index fe6e382ce20..00000000000 --- a/config/ac-macros/ha_tina.m4 +++ /dev/null @@ -1,29 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_CHECK_CSVDB -dnl Sets HAVE_CSV_DB if --with-csv-storage-engine is used -dnl --------------------------------------------------------------------------- -AC_DEFUN([MYSQL_CHECK_CSVDB], [ - AC_ARG_WITH([csv-storage-engine], - [ - --with-csv-storage-engine - Enable the CSV Storage Engine], - [csvdb="$withval"], - [csvdb=no]) - AC_MSG_CHECKING([for csv storage engine]) - - case "$csvdb" in - yes ) - AC_DEFINE([HAVE_CSV_DB], [1], [Builds the CSV Storage Engine]) - AC_MSG_RESULT([yes]) - [csvdb=yes] - ;; - * ) - AC_MSG_RESULT([no]) - [csvdb=no] - ;; - esac - -]) -dnl --------------------------------------------------------------------------- -dnl END OF MYSQL_CHECK_CSV SECTION -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index d8199f5970e..a2f70071e2d 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -675,8 +675,8 @@ dnl Sets BIG_TABLES if --with-big-tables is used dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_BIG_TABLES], [ AC_ARG_WITH([big-tables], - [ - --with-big-tables Support tables with more than 4 G rows even on 32 bit platforms], + AS_HELP_STRING([--with-big-tables], + [Support tables with more than 4 G rows even on 32 bit platforms]), [bigtables="$withval"], [bigtables=no]) AC_MSG_CHECKING([for big tables support]) @@ -703,8 +703,8 @@ dnl Sets MAX_INDEXES dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_MAX_INDEXES], [ AC_ARG_WITH([max-indexes], - [ - --with-max-indexes=\# Sets the maximum number of indexes per table, default 64], + AS_HELP_STRING([--with-max-indexes=N], + [Sets the maximum number of indexes per table, default 64]), [max_indexes="$withval"], [max_indexes=64]) AC_MSG_CHECKING([max indexes per table]) diff --git a/config/ac-macros/openssl.m4 b/config/ac-macros/openssl.m4 index 1f9d53abe01..a23c46eed00 100644 --- a/config/ac-macros/openssl.m4 +++ b/config/ac-macros/openssl.m4 @@ -1,6 +1,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ incs="$1" libs="$2" + eval shrexts=\"$shrext_cmds\" case "$incs---$libs" in ---) for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ @@ -15,7 +16,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \ /usr/freeware/lib32 /usr/local/lib/ ; do # Just to be safe, we test for ".so" anyway - if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext_cmds ; then + if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext ; then OPENSSL_LIB=$d fi done @@ -28,7 +29,7 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ OPENSSL_INCLUDE=-I$incs fi # Just to be safe, we test for ".so" anyway - if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext_cmds ; then + if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext ; then OPENSSL_LIB=$libs fi ;; diff --git a/config/ac-macros/plugins.m4 b/config/ac-macros/plugins.m4 new file mode 100644 index 00000000000..aa28a611e9e --- /dev/null +++ b/config/ac-macros/plugins.m4 @@ -0,0 +1,733 @@ +dnl =========================================================================== +dnl Support for mysql server plugins +dnl =========================================================================== +dnl +dnl WorkLog#3201 +dnl +dnl Framework for pluggable static and dynamic plugins for mysql +dnl +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN([name],[Plugin name], +dnl [Plugin description], +dnl [group,group...]) +dnl +dnl DESCRIPTION +dnl First declaration for a plugin (mandatory). +dnl Adds plugin as member to configuration groups (if specified) +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN],[ + _MYSQL_PLUGIN( + [$1], + [__MYSQL_PLUGIN_]AS_TR_CPP([$1])[__], + m4_default([$2], [$1 plugin]), + m4_default([$3], [plugin for $1]), + m4_default([$4], []), + ) +]) + +AC_DEFUN([_MYSQL_PLUGIN],[ + m4_ifdef([$2], [ + AC_FATAL([Duplicate MYSQL_PLUGIN declaration for $3]) + ],[ + m4_define([$2], [$1]) + _MYSQL_PLUGAPPEND([__mysql_plugin_list__],[$1]) + m4_define([MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), [$3]) + m4_define([MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), [$4]) + _MYSQL_PLUGAPPEND_META([$1], $5) + ]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_STORAGE_ENGINE +dnl +dnl SYNOPSIS +dnl MYSQL_STORAGE_ENGINE([name],[legacy-option],[Storage engine name], +dnl [Storage engine description],[group,group...]) +dnl +dnl DESCRIPTION +dnl Short cut for storage engine declarations +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_STORAGE_ENGINE],[ + MYSQL_PLUGIN([$1], [$3], [$4], [[$5]]) + MYSQL_PLUGIN_DEFINE([$1], [WITH_]AS_TR_CPP([$1])[_STORAGE_ENGINE]) + ifelse([$2],[no],[],[ + _MYSQL_LEGACY_STORAGE_ENGINE( + m4_bpatsubst([$1], -, _), + m4_bpatsubst(m4_default([$2], [$1-storage-engine]), -, _)) + ]) +]) + +AC_DEFUN([_MYSQL_LEGACY_STORAGE_ENGINE],[ +if test "[${with_]$2[+set}]" = set; then + [with_plugin_]$1="[$with_]$2" +fi +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_DEFINE +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DEFINE([name],[MYSQL_CPP_DEFINE]) +dnl +dnl DESCRIPTION +dnl When a plugin is to be statically linked, define the C macro +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_DEFINE],[ + MYSQL_REQUIRE_PLUGIN([$1]) + m4_define([MYSQL_PLUGIN_DEFINE_]AS_TR_CPP([$1]), [$2]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_DIRECTORY +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DIRECTORY([name],[plugin/dir]) +dnl +dnl DESCRIPTION +dnl Adds a directory to the build process +dnl if it contains 'configure' it will be picked up automatically +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_DIRECTORY],[ + MYSQL_REQUIRE_PLUGIN([$1]) + m4_define([MYSQL_PLUGIN_DIRECTORY_]AS_TR_CPP([$1]), [$2]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_STATIC +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a]) +dnl +dnl DESCRIPTION +dnl Declare the name for the static library +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_STATIC],[ + MYSQL_REQUIRE_PLUGIN([$1]) + m4_define([MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), [$2]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_DYNAMIC +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DYNAMIC([name],[myplugin.la]) +dnl +dnl DESCRIPTION +dnl Declare the name for the shared library +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_DYNAMIC],[ + MYSQL_REQUIRE_PLUGIN([$1]) + m4_define([MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]), [$2]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_MANDATORY +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_MANDATORY([name]) +dnl +dnl DESCRIPTION +dnl Marks the specified plugin as a mandatory plugin +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_MANDATORY],[ + MYSQL_REQUIRE_PLUGIN([$1]) + _MYSQL_PLUGIN_MANDATORY([$1], + [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]) + ) +]) + +AC_DEFUN([_MYSQL_PLUGIN_MANDATORY],[ + m4_define([$2], [yes]) + m4_ifdef([$3], [ + AC_FATAL([mandatory plugin $1 has been disabled]) + m4_undefine([$2]) + ]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_DISABLED +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DISABLED([name]) +dnl +dnl DESCRIPTION +dnl Marks the specified plugin as a disabled plugin +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_DISABLED],[ + MYSQL_REQUIRE_PLUGIN([$1]) + _MYSQL_PLUGIN_DISABLED([$1], + [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]) + ) +]) + +AC_DEFUN([_MYSQL_PLUGIN_DISABLED],[ + m4_define([$2], [yes]) + m4_ifdef([$3], [ + AC_FATAL([attempt to disable mandatory plugin $1]) + m4_undefine([$2]) + ]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_DEPENDS +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DEPENDS([name],[prereq,prereq...]) +dnl +dnl DESCRIPTION +dnl Enables other plugins neccessary for the named plugin +dnl Dependency checking is not recursive so if any +dnl required plugin requires further plugins, list them +dnl here too! +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_DEPENDS],[ + MYSQL_REQUIRE_PLUGIN([$1]) + ifelse($#, 2, [ + _MYSQL_PLUGIN_DEPEND([$1], $2) + ], [ + AC_FATAL([bad number of arguments]) + ]) +]) + +AC_DEFUN([_MYSQL_PLUGIN_DEPEND],[ + ifelse($#, 1, [], [$#:$2], [2:], [], [ + MYSQL_REQUIRE_PLUGIN([$2]) + _MYSQL_PLUGAPPEND([__mysql_plugdepends_$1__],[$2]) + _MYSQL_PLUGIN_DEPEND([$1], m4_shift(m4_shift($@))) + ]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_PLUGIN_ACTIONS +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_ACTIONS([name],[PLUGIN_CONFIGURE_STUFF]) +dnl +dnl DESCRIPTION +dnl Declares additional autoconf actions required to configure the plugin +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_PLUGIN_ACTIONS],[ + MYSQL_REQUIRE_PLUGIN([$1]) + m4_ifdef([$2],[ + m4_define([MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]),m4_defn([$2])) + ],[ + m4_define([MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]), [$2]) + ]) +]) + + +dnl --------------------------------------------------------------------------- +dnl Macro: MYSQL_CONFIGURE_PLUGINS +dnl +dnl SYNOPSIS +dnl MYSQL_PLUGIN_DEPENDS([name,name...]) +dnl +dnl DESCRIPTION +dnl Used last, emits all required shell code to configure the plugins +dnl Argument is a list of default plugins or meta-plugin +dnl +dnl --------------------------------------------------------------------------- + +AC_DEFUN([MYSQL_CONFIGURE_PLUGINS],[ + m4_ifdef([__mysql_plugin_configured__],[ + AC_FATAL([cannot use [MYSQL_CONFIGURE_PLUGINS] multiple times]) + ],[ + m4_define([__mysql_plugin_configured__],[done]) + m4_ifdef([__mysql_plugin_list__],[ + _MYSQL_CHECK_PLUGIN_ARGS([$1]) + _MYSQL_CONFIGURE_PLUGINS(m4_bpatsubst(__mysql_plugin_list__, :, [,])) + _MYSQL_EMIT_PLUGIN_ACTIONS(m4_bpatsubst(__mysql_plugin_list__, :, [,])) + AC_SUBST([mysql_se_dirs]) + AC_SUBST([mysql_pg_dirs]) + ]) + ]) +]) + +AC_DEFUN([_MYSQL_CONFIGURE_PLUGINS],[ + ifelse($#, 0, [], $#, 1, [ + _MYSQL_EMIT_CHECK_PLUGIN([$1]) + ],[ + _MYSQL_EMIT_CHECK_PLUGIN([$1]) + _MYSQL_CONFIGURE_PLUGINS(m4_shift($@)) + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_CHECK_PLUGIN],[ + __MYSQL_EMIT_CHECK_PLUGIN( + [$1], + m4_bpatsubst([$1], -, _), + [MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DEFINE_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DIRECTORY_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]) + ) +]) + +AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[ + m4_ifdef([$5],[ + AH_TEMPLATE($5, [Include ]$4[ into mysqld]) + ]) + AC_MSG_CHECKING([whether to use ]$3) + mysql_use_plugin_dir="" + m4_ifdef([$10],[ + if test "X[$mysql_plugin_]$2" = Xyes -a \ + "X[$with_plugin_]$2" != Xno -o \ + "X[$with_plugin_]$2" = Xyes; then + AC_MSG_RESULT([error]) + AC_MSG_ERROR([disabled]) + fi + AC_MSG_RESULT([no]) + ],[ + m4_ifdef([$9],[ + if test "X[$with_plugin_]$2" = Xno; then + AC_MSG_RESULT([error]) + AC_MSG_ERROR([cannot disable mandatory plugin]) + fi + [mysql_plugin_]$2=yes + ]) + if test "X[$with_plugin_]$2" = Xno; then + AC_MSG_RESULT([no]) + else + m4_ifdef([$8],m4_ifdef([$7],[],[[with_plugin_]$2=''])) + if test "X[$mysql_plugin_]$2" != Xyes -a \ + "X[$with_plugin_]$2" != Xyes; then + m4_ifdef([$8],[ + m4_ifdef([$6],[ + if test -d "$srcdir/$6" ; then + mysql_use_plugin_dir="$6" + ]) + AC_SUBST([plugin_]$2[_shared_target], "$8") + AC_SUBST([plugin_]$2[_static_target], [""]) + [with_plugin_]$2=yes + AC_MSG_RESULT([plugin]) + m4_ifdef([$6],[ + else + [mysql_plugin_]$2=no + AC_MSG_RESULT([no]) + fi + ]) + ],[ + [with_plugin_]$2=no + AC_MSG_RESULT([no]) + ]) + else + m4_ifdef([$7],[ + ifelse(m4_bregexp($7, [^lib[^.]+\.a$]), -2, [ +dnl change above "-2" to "0" to enable this section +dnl Although this is "pretty", it breaks libmysqld build + m4_ifdef([$6],[ + mysql_use_plugin_dir="$6" + mysql_plugin_libs="$mysql_plugin_libs -L[\$(top_builddir)]/$6" + ]) + mysql_plugin_libs="$mysql_plugin_libs dnl +[-l]m4_bregexp($7, [^lib\([^.]+\)], [\1])" + ], m4_bregexp($7, [^\\\$]), 0, [ + m4_ifdef([$6],[ + mysql_use_plugin_dir="$6" + ]) + mysql_plugin_libs="$mysql_plugin_libs $7" + ], [ + m4_ifdef([$6],[ + mysql_use_plugin_dir="$6" + mysql_plugin_libs="$mysql_plugin_libs \$(top_builddir)/$6/$7" + ],[ + mysql_plugin_libs="$mysql_plugin_libs $7" + ]) + ]) + m4_ifdef([$5],[ + AC_DEFINE($5) + ]) + AC_SUBST([plugin_]$2[_static_target], "$7") + AC_SUBST([plugin_]$2[_shared_target], [""]) + ],[ + m4_ifdef([$6],[ + AC_MSG_RESULT([error]) + AC_MSG_ERROR([Plugin $1 does not support static linking]) + ],[ + m4_ifdef([$5],[ + AC_DEFINE($5) + AC_SUBST([plugin_]$2[_static_target], ["yes"]) + AC_SUBST([plugin_]$2[_shared_target], [""]) + ]) + ]) + ]) + mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]" + [with_plugin_]$2=yes + AC_MSG_RESULT([yes]) + fi + m4_ifdef([$6],[ + if test -n "$mysql_use_plugin_dir" ; then + mysql_plugin_dirs="$mysql_plugin_dirs $6" + if test -f "$srcdir/$6/configure" ; then + other_configures="$other_configures $6/configure" + else + AC_CONFIG_FILES($6/Makefile) + fi + ifelse(m4_substr($6, 0, 8), [storage/], + [mysql_se_dirs="$mysql_se_dirs ]m4_substr($6, 8)", + m4_substr($6, 0, 7), [plugin/], + [mysql_pg_dirs="$mysql_pg_dirs ]m4_substr($6, 7)", + [AC_FATAL([don't know how to handle plugin dir ]$6)]) + fi + ]) + fi + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_PLUGIN_ACTIONS],[ + ifelse($#, 0, [], $#, 1, [ + _MYSQL_EMIT_PLUGIN_ACTION([$1]) + ],[ + _MYSQL_EMIT_PLUGIN_ACTION([$1]) + _MYSQL_EMIT_PLUGIN_ACTIONS(m4_shift($@)) + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_PLUGIN_ACTION],[ + __MYSQL_EMIT_PLUGIN_ACTION( + [$1], + m4_bpatsubst([$1], -, _), + [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]) + ) +]) + + +AC_DEFUN([__MYSQL_EMIT_PLUGIN_ACTION],[ + m4_ifdef([$3], [], [ + if test "X[$with_plugin_]$2" = Xyes; then + if test "X[$plugin_]$2[_static_target]" = X -a \ + "X[$plugin_]$2[_shared_target]" = X; then + AC_MSG_ERROR([that's strange, $1 failed sanity check]) + fi + $4 + fi + ]) +]) + + + +dnl =========================================================================== +dnl Private helper macros +dnl =========================================================================== + + +dnl SYNOPSIS +dnl MYSQL_REQUIRE_PLUGIN([name]) +dnl +dnl DESCRIPTION +dnl Checks that the specified plugin does exist + +AC_DEFUN([MYSQL_REQUIRE_PLUGIN],[ + _MYSQL_REQUIRE_PLUGIN([$1], [__MYSQL_PLUGIN_]AS_TR_CPP([$1])[__]) +]) + +define([_MYSQL_REQUIRE_PLUGIN],[ + ifdef([$2],[ + ifelse($2, [$1], [], [ + AC_FATAL([Misspelt MYSQL_PLUGIN declaration for $1]) + ]) + ],[ + AC_FATAL([Missing MYSQL_PLUGIN declaration for $1]) + ]) +]) + + +dnl --------------------------------------------------------------------------- + + +dnl SYNOPSIS +dnl _MYSQL_EMIT_METAPLUGINS([name,name...]) +dnl +dnl DESCRIPTION +dnl Emits shell code for metaplugins + +AC_DEFUN([_MYSQL_EMIT_METAPLUGINS], [ifelse($#, 0, [], $#, 1, +[_MYSQL_EMIT_METAPLUGIN([$1], [__mysql_]m4_bpatsubst($1, -, _)[_plugins__]) +], +[_MYSQL_EMIT_METAPLUGIN([$1], [__mysql_]m4_bpatsubst($1, -, _)[_plugins__]) +_MYSQL_EMIT_METAPLUGINS(m4_shift($@))]) +]) + +AC_DEFUN([_MYSQL_EMIT_METAPLUGIN], [ + [$1] ) +m4_ifdef([$2], [ + mysql_plugins='m4_bpatsubst($2, :, [ ])' +],[ + mysql_plugins='' +]) + ;; +]) + + +dnl --------------------------------------------------------------------------- + + +dnl SYNOPSIS +dnl _MYSQL_PLUGAPPEND([name],[to-append]) +dnl +dnl DESCRIPTION +dnl Helper macro for appending to colon-delimited lists +dnl Optinal 3rd argument is for actions only required when defining +dnl macro named for the first time. + +AC_DEFUN([_MYSQL_PLUGAPPEND],[ + m4_ifdef([$1],[ + m4_define([__plugin_append_tmp__], m4_defn([$1])) + m4_undefine([$1]) + m4_define([$1], __plugin_append_tmp__[:$2]) + m4_undefine([__plugin_append_tmp__]) + ],[ + m4_define([$1], [$2]) + $3 + ]) +]) + + +dnl SYNOPSIS +dnl _MYSQL_PLUGAPPEND_META([name],[meta,meta...]) +dnl +dnl DESCRIPTION +dnl Helper macro for adding plugins to meta plugins + +AC_DEFUN([_MYSQL_PLUGAPPEND_META],[ + ifelse($#, 1, [], [$#:$2], [2:], [], [$2], [all], [ + AC_FATAL([protected plugin group: all]) + ], [$2], [none], [ + AC_FATAL([protected plugin group: none]) + ],[ + _MYSQL_PLUGAPPEND([__mysql_$1_configs__],[$2]) + _MYSQL_PLUGAPPEND([__mysql_]m4_bpatsubst($2, -, _)[_plugins__],[$1], [ + _MYSQL_PLUGAPPEND([__mysql_metaplugin_list__],[$2]) + ]) + _MYSQL_PLUGAPPEND_META([$1], m4_shift(m4_shift($@))) + ]) +]) + + +dnl --------------------------------------------------------------------------- + + +dnl SYNOPSIS +dnl MYSQL_LIST_PLUGINS +dnl +dnl DESCRIPTION +dnl Emits formatted list of declared plugins + +AC_DEFUN([MYSQL_LIST_PLUGINS],[dnl + m4_ifdef([__mysql_plugin_list__],[dnl + _MYSQL_LIST_PLUGINS(m4_bpatsubst(__mysql_plugin_list__, :, [,]))dnl + ])dnl +]) + +AC_DEFUN([_MYSQL_LIST_PLUGINS],[dnl + ifelse($#, 0, [], $#, 1, [dnl + MYSQL_SHOW_PLUGIN([$1])dnl + ],[dnl + MYSQL_SHOW_PLUGIN([$1])dnl + _MYSQL_LIST_PLUGINS(m4_shift($@))dnl + ])dnl +]) + +AC_DEFUN([MYSQL_SHOW_PLUGIN],[ + _MYSQL_SHOW_PLUGIN( + [$1], + [$1-plugin], + [MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DESC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DEFINE_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DIRECTORY_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]), + __mysql_[$1]_configs__, + ) +]) + +AC_DEFUN([_MYSQL_SHOW_PLUGIN],[dnl + === $3 === + Plugin Name: [$1] + Description: $4 + Supports build: _PLUGIN_BUILD_TYPE([$7],[$8])[]dnl +m4_ifdef([$12],[ + Configurations: m4_bpatsubst($12, :, [, ])])[]dnl +m4_ifdef([$10],[ + Status: disabled])[]dnl +m4_ifdef([$9],[ + Status: mandatory])[]dnl +]) + +AC_DEFUN([_PLUGIN_BUILD_TYPE], +[m4_ifdef([$1],[static ]m4_ifdef([$2],[and dnl +]))[]m4_ifdef([$2],[dynamic],[m4_ifdef([$1],[],[static])])]) + + +dnl --------------------------------------------------------------------------- + + +AC_DEFUN([_MYSQL_EMIT_PLUGINS],[ + ifelse($#, 0, [], [$#:$1], [1:], [], [ + m4_ifdef([MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]), [], [ + m4_define([MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1]),[ ]) + ]) + [$1] ) + m4_ifdef([MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]),[ + AC_MSG_ERROR([plugin $1 is disabled]) + ],[ + _MYSQL_EMIT_PLUGIN_ENABLE([$1], m4_bpatsubst([$1], -, _), + [MYSQL_PLUGIN_NAME_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), + [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1])) + ]) + ;; + _MYSQL_EMIT_PLUGINS(m4_shift($@)) + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_PLUGIN_ENABLE],[ + m4_ifdef([$5],m4_ifdef([$4],[ + [mysql_plugin_]$2=yes + ],[ + AC_MSG_WARN([$3 can only be built as a plugin]) + ]),[ + [mysql_plugin_]$2=yes + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_PLUGIN_DEPENDS], [ + ifelse($#, 0, [], [$#:$1], [1:], [], [ + _MYSQL_EMIT_CHECK_DEPENDS(m4_bpatsubst([$1], -, _), + [__mysql_plugdepends_$1__]) + _MYSQL_EMIT_PLUGIN_DEPENDS(m4_shift($@)) + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_CHECK_DEPENDS], [ + m4_ifdef([$2], [ + if test "X[$mysql_plugin_]$1" = Xyes -a \ + "X[$with_plugin_]$1" != Xno -o \ + "X[$with_plugin_]$1" = Xyes; then + _MYSQL_EMIT_PLUGIN_DEPENDENCIES(m4_bpatsubst($2, :, [,])) + fi + ]) +]) + +AC_DEFUN([_MYSQL_EMIT_PLUGIN_DEPENDENCIES], [ + ifelse([$1], [], [], [ + m4_ifdef([MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]),[ + AC_MSG_ERROR([depends upon disabled plugin $1]) + ],[ + [mysql_plugin_]m4_bpatsubst([$1], -, _)=yes + if test "X[$with_plugin_]m4_bpatsubst([$1], -, _)" = Xno; then + AC_MSG_ERROR([depends upon disabled plugin $1]) + fi + ]) + _MYSQL_EMIT_PLUGIN_DEPENDENCIES(m4_shift($@)) + ]) +]) + +dnl SYNOPSIS +dnl _MYSQL_CHECK_PLUGIN_ARGS([plugin],[plugin]...) +dnl +dnl DESCRIPTION +dnl Emits shell script for checking configure arguments +dnl Arguments to this macro is default value for selected plugins + +AC_DEFUN([_MYSQL_CHECK_PLUGIN_ARGS],[ + __MYSQL_CHECK_PLUGIN_ARGS(m4_default([$1], [none])) +]) + +AC_DEFUN([__MYSQL_CHECK_PLUGIN_ARGS],[ + AC_ARG_WITH([plugins], +AS_HELP_STRING([--with-plugins=PLUGIN[[[[[,PLUGIN..]]]]]], + [Plugins to include in mysqld. (default is: $1) Must be a + configuration name or a comma separated list of plugins.]) +AS_HELP_STRING([], + [Available configurations are:] dnl +m4_bpatsubst([none:]m4_ifdef([__mysql_metaplugin_list__], + __mysql_metaplugin_list__:)[all], :, [ ])[.]) +AS_HELP_STRING([], + [Available plugins are:] dnl +m4_bpatsubst(__mysql_plugin_list__, :, [ ])[.]) +AS_HELP_STRING([--without-plugin-PLUGIN], + [Disable the named plugin from being built. Otherwise, for + plugins which are not selected for inclusion in mysqld will be + built dynamically (if supported)]) +AS_HELP_STRING([--with-plugin-PLUGIN], + [Forces the named plugin to be linked into mysqld statically.]), + [mysql_plugins="`echo $withval | tr ',.:;*[]' ' '`"], + [mysql_plugins=['$1']]) + +m4_divert_once([HELP_VAR_END],[ +Description of plugins: +MYSQL_LIST_PLUGINS]) + + case "$mysql_plugins" in + all ) + mysql_plugins='m4_bpatsubst(__mysql_plugin_list__, :, [ ])' + ;; + none ) + mysql_plugins='' + ;; +m4_ifdef([__mysql_metaplugin_list__],[ +_MYSQL_EMIT_METAPLUGINS(m4_bpatsubst(__mysql_metaplugin_list__, :, [,])) +]) + esac + + for plugin in $mysql_plugins; do + case "$plugin" in + all | none ) + AC_MSG_ERROR([bad plugin name: $plugin]) + ;; +_MYSQL_EMIT_PLUGINS(m4_bpatsubst(__mysql_plugin_list__, :, [,])) + * ) + AC_MSG_ERROR([unknown plugin: $plugin]) + ;; + esac + done + + _MYSQL_EMIT_PLUGIN_DEPENDS(m4_bpatsubst(__mysql_plugin_list__, :, [,])) +]) + +dnl =========================================================================== diff --git a/config/ac-macros/storage.m4 b/config/ac-macros/storage.m4 deleted file mode 100644 index 4148aed818d..00000000000 --- a/config/ac-macros/storage.m4 +++ /dev/null @@ -1,55 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: MYSQL_STORAGE_ENGINE -dnl -dnl What it does: -dnl creates --with-xxx configure option -dnl adds HAVE_XXX to config.h -dnl appends &xxx_hton, to the list of hanldertons -dnl appends a dir to the list of source directories -dnl appends ha_xxx.cc to the list of handler files -dnl -dnl all names above are configurable with reasonable defaults. -dnl -dnl --------------------------------------------------------------------------- - -AC_DEFUN([MYSQL_STORAGE_ENGINE], -[_MYSQL_STORAGE_ENGINE( -[$1], dnl name -m4_default([$2], [$1 storage engine]), dnl verbose name -m4_default([$3], [$1-storage-engine]), dnl with-name -m4_default([$4], no), dnl default -m4_default([$5], [WITH_]AS_TR_CPP([$1])[_STORAGE_ENGINE]), -m4_default([$6], $1[_hton]), dnl hton -m4_default([$7], []), dnl path to the code -m4_default([$8], [ha_$1.o]), dnl path to the handler in -m4_default([$9], []), dnl path to extra libraries -[$10], dnl code-if-set -)]) - -AC_DEFUN([_MYSQL_STORAGE_ENGINE], -[ -AC_ARG_WITH([$3], AS_HELP_STRING([--with-$3], [enable $2 (default is $4)]), -[], [ [with_]m4_bpatsubst([$3], -, _)=['$4']]) -AC_CACHE_CHECK([whether to use $2], [mysql_cv_use_]m4_bpatsubst([$3], -, _), -[mysql_cv_use_]m4_bpatsubst([$3], -, _)=[$with_]m4_bpatsubst([$3], -, _)) -AH_TEMPLATE([$5], [Build $2]) -if test "[$mysql_cv_use_]m4_bpatsubst([$3], -, _)" != no; then -if test "$6" != "no" -then - AC_DEFINE([$5]) - mysql_se_decls="${mysql_se_decls},$6" - mysql_se_htons="${mysql_se_htons},&$6" - if test "$8" != "no" - then - mysql_se_objs="$mysql_se_objs $8" - fi - mysql_se_dirs="$mysql_se_dirs $7" - mysql_se_libs="$mysql_se_libs $9" -else - mysql_se_plugins="$mysql_se_plugins $7" -fi -$10 -fi -]) - -dnl --------------------------------------------------------------------------- diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index 906a65a2fc3..f6eee32ff84 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -11,8 +11,11 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ AC_MSG_RESULT([using bundled yaSSL]) AC_CONFIG_FILES(extra/yassl/Makefile dnl extra/yassl/taocrypt/Makefile dnl + extra/yassl/taocrypt/benchmark/Makefile dnl extra/yassl/taocrypt/src/Makefile dnl - extra/yassl/src/Makefile) + extra/yassl/taocrypt/test/Makefile dnl + extra/yassl/src/Makefile dnl + extra/yassl/testsuite/Makefile) yassl_dir="yassl" yassl_libs="-L\$(top_srcdir)/extra/yassl/src -lyassl -L\$(top_srcdir)/extra/yassl/taocrypt/src -ltaocrypt" yassl_includes="-I\$(top_srcdir)/extra/yassl/include" diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4 index 23cc132aca8..713e7072c6f 100644 --- a/config/ac-macros/zlib.m4 +++ b/config/ac-macros/zlib.m4 @@ -90,8 +90,9 @@ case $SYSTEM_TYPE in ;; *) # Just to be safe, we test for ".so" anyway + eval shrexts=\"$shrext_cmds\" if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \ - -f "$mysql_zlib_dir/lib/libz$shrext_cmds" \) \ + -f "$mysql_zlib_dir/lib/libz$shrext" \) \ -a -f "$mysql_zlib_dir/include/zlib.h"; then ZLIB_INCLUDES="-I$mysql_zlib_dir/include" ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz" diff --git a/configure.in b/configure.in index 2fde26d5930..e159a5803f1 100644 --- a/configure.in +++ b/configure.in @@ -31,7 +31,7 @@ sinclude(config/ac-macros/alloca.m4) sinclude(config/ac-macros/check_cpu.m4) sinclude(config/ac-macros/character_sets.m4) sinclude(config/ac-macros/compiler_flag.m4) -sinclude(config/ac-macros/storage.m4) +sinclude(config/ac-macros/plugins.m4) sinclude(config/ac-macros/ha_berkeley.m4) sinclude(config/ac-macros/ha_ndbcluster.m4) sinclude(config/ac-macros/large_file.m4) @@ -51,7 +51,6 @@ romanian russian serbian slovak spanish swedish ukrainian" ##### ##### - AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) @@ -196,6 +195,7 @@ then else AC_PATH_PROG(AS, as, as) fi + # Still need ranlib for readline; local static use only so no libtool. AC_PROG_RANLIB # We use libtool @@ -207,6 +207,13 @@ AC_PROG_LIBTOOL LIBTOOL="$LIBTOOL --preserve-dup-deps" AC_SUBST(LIBTOOL)dnl +AC_SUBST(NM)dnl + +# NM= "$NM -X64" +#archive_expsym_cmds= `echo "$archive_expsym_cmds" | sed -e '/"$(CC)"//'` +#archive_expsym_cmds= "$CC -q64 $archive_expsym_cmds" +# CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-ansi//; s/-pedantic//; s/-Wcheck//'` + #AC_LIBTOOL_DLOPEN AC_LIBTOOL_WIN32_DLL AC_DISABLE_FAST_INSTALL AC_DISABLE_SHARED AC_DISABLE_STATIC # AC_PROG_INSTALL @@ -482,7 +489,7 @@ then AC_MSG_ERROR([MySQL requires an ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.]) fi -NOINST_LDFLAGS= +NOINST_LDFLAGS="-static" static_nss="" STATIC_NSS_FLAGS="" @@ -705,9 +712,8 @@ AC_CHECK_FUNC(yp_get_default_domain, , AC_CHECK_FUNC(p2open, , AC_CHECK_LIB(gen, p2open)) # This may get things to compile even if bind-8 is installed AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind)) -# For crypt() on Linux -AC_CHECK_LIB(crypt, crypt) -AC_CHECK_FUNC(crypt, AC_DEFINE([HAVE_CRYPT], [1], [crypt])) +# Check if crypt() exists in libc or libcrypt, sets LIBS if needed +AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt])) # For sem_xxx functions on Solaris 2.6 AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init)) @@ -1616,7 +1622,7 @@ fi # If we should allow error injection tests AC_ARG_WITH(error-inject, - [ --with-error-inject Enable error injection in MySQL Server], + AC_HELP_STRING([--with-error-inject],[Enable error injection in MySQL Server]), [ with_error_inject=$withval ], [ with_error_inject=no ]) @@ -2189,6 +2195,102 @@ then fi AC_MSG_RESULT("$netinet_inc") +#-------------------------------------------------------------------- +# Check for requested features +#-------------------------------------------------------------------- + +MYSQL_CHECK_BIG_TABLES +MYSQL_CHECK_MAX_INDEXES +MYSQL_CHECK_REPLICATION +MYSQL_CHECK_VIO +MYSQL_CHECK_OPENSSL +MYSQL_CHECK_YASSL + +#-------------------------------------------------------------------- +# Declare our plugin modules +# Has to be done late, as the plugin may need to check for existence of +# functions tested above +#-------------------------------------------------------------------- + +MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine], + [Archive Storage Engine], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(archive, [storage/archive]) +MYSQL_PLUGIN_STATIC(archive, [libarchive.a]) +MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la]) + +MYSQL_STORAGE_ENGINE(berkeley, berkeley-db, [BerkeleyDB Storage Engine], + [Transactional Tables using BerkeleyDB], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(berkeley,[storage/bdb]) +MYSQL_PLUGIN_STATIC(berkeley, [[\$(bdb_libs_with_path)]]) +MYSQL_PLUGIN_ACTIONS(berkeley, [MYSQL_SETUP_BERKELEY_DB]) + +MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine], + [Basic Write-only Read-never tables], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole]) +MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a]) +MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la]) + +MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine], + [Stores tables in text CSV format]) +MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv]) +MYSQL_PLUGIN_STATIC(csv, [libcsv.a]) +MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging + +MYSQL_STORAGE_ENGINE(example,, [Example Storage Engine], + [Skeleton for Storage Engines for developers], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(example, [storage/example]) +MYSQL_PLUGIN_STATIC(example, [libexample.a]) +MYSQL_PLUGIN_DYNAMIC(example, [ha_example.la]) + +MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine], + [Connects to tables on remote MySQL servers], [max,max-no-ndb]) + +MYSQL_PLUGIN(ftexample, [Simple Parser], + [Simple full-text parser plugin]) +MYSQL_PLUGIN_DIRECTORY(ftexample, [plugin/fulltext]) +MYSQL_PLUGIN_DYNAMIC(ftexample, [mypluglib.la]) + +MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine], + [Volatile memory based tables]) +MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap]) +MYSQL_PLUGIN_STATIC(heap, [libheap.a]) +MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables + +MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], + [Transactional Tables using InnoDB], [max,max-no-ndb]) +MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) +MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) +MYSQL_PLUGIN_ACTIONS(innobase, [ + AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) + AC_SUBST(innodb_system_libs) +]) + +MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine], + [Traditional non-transactional MySQL tables]) +MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam]) +MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a]) +MYSQL_PLUGIN_MANDATORY(myisam) dnl Default + +MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine], + [Merge multiple MySQL tables into one]) +MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg]) +MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a]) +MYSQL_PLUGIN_MANDATORY(myisammrg) + +MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine], + [High Availability Clustered tables], [max]) +MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb]) +MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]]) +MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER]) + +MYSQL_STORAGE_ENGINE(partition, partition, [Partition Support], + [MySQL Partitioning Support], [max,max-no-ndb]) + +dnl -- ndbcluster requires partition to be enabled +MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition]) + +MYSQL_CONFIGURE_PLUGINS([none]) + # Only build client code? AC_ARG_WITH(server, [ --without-server Only build the client.], @@ -2242,21 +2344,18 @@ fi tools_dirs="" AC_ARG_WITH([mysqlmanager], - AC_HELP_STRING([--with-mysqlmanager], [Build the mysqlmanager binary: yes/no (default: build if server is built.)]), - [if test "x${withval}" != "xno"; then - tools_dirs="$tools_dirs server-tools" - fi], - [if test "x${with_server}" = "xyes"; then - tools_dirs="$tools_dirs server-tools" - fi] -) + AC_HELP_STRING([--with-mysqlmanager], [Build the mysqlmanager binary: yes/no (default: build if server is built.)]),,) + +if test "$with_mysqlmanager" = "yes" -o \ + '(' "$with_mysqlmanager:$with_server" = ":yes" -a \ + -d "$srcdir/server-tools" ')' ; then + tools_dirs="$tools_dirs server-tools" + AC_CONFIG_FILES(server-tools/Makefile server-tools/instance-manager/Makefile) +fi AC_SUBST(tools_dirs) #MYSQL_CHECK_CPU -MYSQL_CHECK_VIO -MYSQL_CHECK_OPENSSL -MYSQL_CHECK_YASSL libmysqld_dirs= linked_libmysqld_targets= @@ -2421,73 +2520,6 @@ AC_SUBST(readline_basedir) AC_SUBST(readline_link) AC_SUBST(readline_h_ln_cmd) -MYSQL_CHECK_BIG_TABLES -MYSQL_CHECK_MAX_INDEXES -MYSQL_CHECK_REPLICATION - -MYSQL_STORAGE_ENGINE(innobase,,innodb,,,,innobase,ha_innodb.o,[ dnl - \$(top_builddir)/storage/innobase/usr/libusr.a dnl - \$(top_builddir)/storage/innobase/srv/libsrv.a dnl - \$(top_builddir)/storage/innobase/dict/libdict.a dnl - \$(top_builddir)/storage/innobase/que/libque.a dnl - \$(top_builddir)/storage/innobase/srv/libsrv.a dnl - \$(top_builddir)/storage/innobase/ibuf/libibuf.a dnl - \$(top_builddir)/storage/innobase/row/librow.a dnl - \$(top_builddir)/storage/innobase/pars/libpars.a dnl - \$(top_builddir)/storage/innobase/btr/libbtr.a dnl - \$(top_builddir)/storage/innobase/trx/libtrx.a dnl - \$(top_builddir)/storage/innobase/read/libread.a dnl - \$(top_builddir)/storage/innobase/usr/libusr.a dnl - \$(top_builddir)/storage/innobase/buf/libbuf.a dnl - \$(top_builddir)/storage/innobase/ibuf/libibuf.a dnl - \$(top_builddir)/storage/innobase/eval/libeval.a dnl - \$(top_builddir)/storage/innobase/log/liblog.a dnl - \$(top_builddir)/storage/innobase/fsp/libfsp.a dnl - \$(top_builddir)/storage/innobase/fut/libfut.a dnl - \$(top_builddir)/storage/innobase/fil/libfil.a dnl - \$(top_builddir)/storage/innobase/lock/liblock.a dnl - \$(top_builddir)/storage/innobase/mtr/libmtr.a dnl - \$(top_builddir)/storage/innobase/page/libpage.a dnl - \$(top_builddir)/storage/innobase/rem/librem.a dnl - \$(top_builddir)/storage/innobase/thr/libthr.a dnl - \$(top_builddir)/storage/innobase/sync/libsync.a dnl - \$(top_builddir)/storage/innobase/data/libdata.a dnl - \$(top_builddir)/storage/innobase/mach/libmach.a dnl - \$(top_builddir)/storage/innobase/ha/libha.a dnl - \$(top_builddir)/storage/innobase/dyn/libdyn.a dnl - \$(top_builddir)/storage/innobase/mem/libmem.a dnl - \$(top_builddir)/storage/innobase/sync/libsync.a dnl - \$(top_builddir)/storage/innobase/ut/libut.a dnl - \$(top_builddir)/storage/innobase/os/libos.a dnl - \$(top_builddir)/storage/innobase/ut/libut.a],[ - AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) - AC_SUBST(innodb_includes) - AC_SUBST(innodb_libs) - AC_SUBST(innodb_system_libs) - other_configures="$other_configures storage/innobase/configure" -]) - -MYSQL_STORAGE_ENGINE(berkeley,,berkeley-db,,,,bdb,,,[ - MYSQL_SETUP_BERKELEY_DB -]) -MYSQL_STORAGE_ENGINE(example,,,,,,example,no, - \$(top_builddir)/storage/example/libexample.a,[ - AC_CONFIG_FILES(storage/example/Makefile) -]) -MYSQL_STORAGE_ENGINE(archive,,,,,,archive,, - \$(top_builddir)/storage/archive/libarchive.a, [ - AC_CONFIG_FILES(storage/archive/Makefile) -]) -MYSQL_STORAGE_ENGINE(csv,,,"yes",,tina_hton,csv,no, - \$(top_builddir)/storage/csv/libcsv.a,[ - AC_CONFIG_FILES(storage/csv/Makefile) -]) -MYSQL_STORAGE_ENGINE(blackhole) -MYSQL_STORAGE_ENGINE(federated) -MYSQL_STORAGE_ENGINE(ndbcluster,,ndbcluster,,,,ndb,,,[ - MYSQL_SETUP_NDBCLUSTER -]) -MYSQL_STORAGE_ENGINE(partition,,partition) # If we have threads generate some library functions and test programs sql_server_dirs= @@ -2544,7 +2576,7 @@ then AC_SUBST(THREAD_LOBJECTS) server_scripts="mysqld_safe mysql_install_db" sql_server_dirs="strings mysys dbug extra regex" - mysql_se_dirs="myisam myisammrg heap $mysql_se_dirs" + sql_server="$sql_server vio sql" fi @@ -2560,12 +2592,9 @@ AC_SUBST(sql_server) AC_SUBST(thread_dirs) AC_SUBST(server_scripts) -AC_SUBST(mysql_se_dirs) -AC_SUBST(mysql_se_libs) -AC_SUBST(mysql_se_objs) -AC_SUBST(mysql_se_htons) -AC_SUBST(mysql_se_decls) -AC_SUBST(mysql_se_plugins) +AC_SUBST(mysql_plugin_dirs) +AC_SUBST(mysql_plugin_libs) +AC_SUBST(mysql_plugin_defs) # Now that sql_client_dirs and sql_server_dirs are stable, determine the union. @@ -2607,25 +2636,18 @@ AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS) # Output results AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl - unittest/Makefile dnl - unittest/mytap/Makefile unittest/mytap/t/Makefile dnl + unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl unittest/mysys/Makefile unittest/examples/Makefile dnl - strings/Makefile regex/Makefile storage/Makefile storage/heap/Makefile dnl - storage/myisam/Makefile storage/myisammrg/Makefile dnl + strings/Makefile regex/Makefile storage/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl libmysql/Makefile client/Makefile dnl pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl - sql/handlerton.cc sql-common/Makefile dnl - dbug/Makefile scripts/Makefile dnl - include/Makefile dnl - server-tools/Makefile server-tools/instance-manager/Makefile dnl + sql/sql_builtin.cc sql-common/Makefile dnl + dbug/Makefile scripts/Makefile include/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl mysql-test/ndb/Makefile netware/Makefile dnl - include/mysql_version.h dnl - plugin/Makefile dnl - plugin/fulltext/Makefile dnl - win/Makefile) + include/mysql_version.h plugin/Makefile win/Makefile) AC_CONFIG_COMMANDS([default], , test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h) AC_OUTPUT diff --git a/extra/yassl/Makefile.am b/extra/yassl/Makefile.am index 3ce5e2632cc..60868f82add 100644 --- a/extra/yassl/Makefile.am +++ b/extra/yassl/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = taocrypt src +SUBDIRS = taocrypt src testsuite EXTRA_DIST = yassl.dsp yassl.dsw yassl.vcproj $(wildcard mySTL/*.hpp) \ cmakelists.txt diff --git a/extra/yassl/README b/extra/yassl/README index 198a1031cb7..ad59fe3965e 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -1,4 +1,137 @@ -yaSSL Release notes, version 0.9.6 +yaSSL Release notes, version 1.2.2 (03/27/06) + + + This release of yaSSL contains minor bug fixes and portability enhancements. + +See build instructions below under 1.0.6: + + + +*******************yaSSL Release notes, version 1.2.0 + + + This release of yaSSL contains minor bug fixes, portability enhancements, + Diffie-Hellman compatibility fixes for other servers and client, + optimization improvements, and x86 ASM changes. + +See build instructions below under 1.0.6: + + + +*****************yaSSL Release notes, version 1.1.5 + + This release of yaSSL contains minor bug fixes, portability enhancements, + and user requested changes including the ability to add all certificates in + a directory, more robust socket handling, no new overloading unless + requested, and an SSL_VERIFY_NONE option. + + +See build instructions below under 1.0.6: + + + +******************yaSSL Release notes, version 1.0.6 + +This release of yaSSL contains minor bug fixes, portability enhancements, +x86 assembly for ARC4, SHA, MD5, and RIPEMD, --enable-ia32-asm configure +option, and a security patch for certificate chain processing. + +--To build on Linux, Solaris, *BSD, Mac OS X, or Cygwin: + + ./configure + make + + run testsuite from yaSSL-Home/testsuite to test the build + +to make a release build: + + ./configure --disable-debug + make + + run testsuite from yaSSL-Home/testsuite to test the build + + +--To build on Win32 + +Choose (Re)Build All from the project workspace + +run Debug\testsuite.exe from yaSSL-Home\testsuite to test the build + + +--To enable ia32 assembly for TaoCrypt ciphers and message digests + + On MSVC this is always on + + On GCC **, use ./configure --enable-ia32-asm + + ** This isn't on by default because of the use of intel syntax and the + problem that olders versions of gas have with some addressing statements. + If you enable this and get assemler errors during compilation or can't + pass the TaoCrypt tests, please send todd@yassl.com a message and disable + this option in the meantime. + + +***************** yaSSL Release notes, version 1.0.5 + +This release of yaSSL contains minor bug fixes, portability enhancements, +x86 assembly for AES, 3DES, BLOWFISH, and TWOFISH, --without-debug configure +option, and --enable-kernel-mode configure option for using TaoCrypt with +kernel modules. + +--To build on Linux, Solaris, *BSD, Mac OS X, or Cygwin: + + ./configure + make + + run testsuite from yaSSL-Home/testsuite to test the build + +to make a release build: + + ./configure --without-debug + make + + run testsuite from yaSSL-Home/testsuite to test the build + + +--To build on Win32 + +Choose (Re)Build All from the project workspace + +run Debug\testsuite.exe from yaSSL-Home\testsuite to test the build + + +******************yaSSL Release notes, version 1.0.1 + +This release of yaSSL contains minor bug fixes, portability enhancements, +GCC 3.4.4 support, MSVC 2003 support, and more documentation. + +Please see build instructions in the release notes for 0.9.6 below. + + +******************yaSSL Release notes, version 1.0 + +This release of yaSSL contains minor bug fixes, portability enhancements, +GCC 4.0 support, testsuite, improvements, and API additions. + +Please see build instructions in the release notes for 0.9.6 below. + + +******************yaSSL Release notes, version 0.9.9 + +This release of yaSSL contains minor bug fixes, portability enchancements, +MSVC 7 support, memory improvements, and API additions. + +Please see build instructions in the release notes for 0.9.6 below. + + +******************yaSSL Release notes, version 0.9.8 + +This release of yaSSL contains minor bug fixes and portability enchancements. + +Please see build instructions in the release notes for 0.9.6 below. + + +******************yaSSL Release notes, version 0.9.6 This release of yaSSL contains minor bug fixes, removal of STL support, and removal of exceptions and rtti so that the library can be linked without the diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp new file mode 100644 index 00000000000..704a8e76637 --- /dev/null +++ b/extra/yassl/examples/client/client.cpp @@ -0,0 +1,96 @@ +/* client.cpp */ + +#include "../../testsuite/test.hpp" + +//#define TEST_RESUME + + +void client_test(void* args) +{ +#ifdef _WIN32 + WSADATA wsd; + WSAStartup(0x0002, &wsd); +#endif + + SOCKET_T sockfd = 0; + int argc = 0; + char** argv = 0; + + set_args(argc, argv, *static_cast(args)); + tcp_connect(sockfd); + + SSL_METHOD* method = TLSv1_client_method(); + SSL_CTX* ctx = SSL_CTX_new(method); + + set_certs(ctx); + SSL* ssl = SSL_new(ctx); + + SSL_set_fd(ssl, sockfd); + + if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed"); + showPeer(ssl); + + const char* cipher = 0; + int index = 0; + char list[1024]; + strcpy(list, "cipherlist"); + while ( (cipher = SSL_get_cipher_list(ssl, index++)) ) { + strcat(list, ":"); + strcat(list, cipher); + } + printf("%s\n", list); + printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl)); + + char msg[] = "hello yassl!"; + if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) + err_sys("SSL_write failed"); + + char reply[1024]; + reply[SSL_read(ssl, reply, sizeof(reply))] = 0; + printf("Server response: %s\n", reply); + +#ifdef TEST_RESUME + SSL_SESSION* session = SSL_get_session(ssl); + SSL* sslResume = SSL_new(ctx); +#endif + + SSL_shutdown(ssl); + SSL_free(ssl); + +#ifdef TEST_RESUME + tcp_connect(sockfd); + SSL_set_fd(sslResume, sockfd); + SSL_set_session(sslResume, session); + + if (SSL_connect(sslResume) != SSL_SUCCESS) err_sys("SSL resume failed"); + + if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg)) + err_sys("SSL_write failed"); + + reply[SSL_read(sslResume, reply, sizeof(reply))] = 0; + printf("Server response: %s\n", reply); + + SSL_shutdown(sslResume); + SSL_free(sslResume); +#endif // TEST_RESUME + + SSL_CTX_free(ctx); + ((func_args*)args)->return_code = 0; +} + + +#ifndef NO_MAIN_DRIVER + + int main(int argc, char** argv) + { + func_args args; + + args.argc = argc; + args.argv = argv; + + client_test(&args); + return args.return_code; + } + +#endif // NO_MAIN_DRIVER + diff --git a/extra/yassl/examples/client/client.dsp b/extra/yassl/examples/client/client.dsp new file mode 100644 index 00000000000..1caa585dadb --- /dev/null +++ b/extra/yassl/examples/client/client.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="client" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=client - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "client.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "client.mak" CFG="client - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "client - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "client - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "client - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /O2 /I "..\..\taocrypt\include" /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "client - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "..\..\include" /I "..\..\taocrypt\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "client - Win32 Release" +# Name "client - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\client.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp new file mode 100644 index 00000000000..ca557cca8af --- /dev/null +++ b/extra/yassl/examples/echoclient/echoclient.cpp @@ -0,0 +1,89 @@ +/* echoclient.cpp */ + +#include "../../testsuite/test.hpp" + + +void echoclient_test(void* args) +{ +#ifdef _WIN32 + WSADATA wsd; + WSAStartup(0x0002, &wsd); +#endif + + SOCKET_T sockfd = 0; + int argc = 0; + char** argv = 0; + + FILE* fin = stdin; + FILE* fout = stdout; + + bool inCreated = false; + bool outCreated = false; + + set_args(argc, argv, *static_cast(args)); + if (argc >= 2) { + fin = fopen(argv[1], "r"); + inCreated = true; + } + if (argc >= 3) { + fout = fopen(argv[2], "w"); + outCreated = true; + } + + if (!fin) err_sys("can't open input file"); + if (!fout) err_sys("can't open output file"); + + tcp_connect(sockfd); + + SSL_METHOD* method = TLSv1_client_method(); + SSL_CTX* ctx = SSL_CTX_new(method); + set_certs(ctx); + SSL* ssl = SSL_new(ctx); + + SSL_set_fd(ssl, sockfd); + if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed"); + + char send[1024]; + char reply[1024]; + + while (fgets(send, sizeof(send), fin)) { + + int sendSz = strlen(send) + 1; + if (SSL_write(ssl, send, sendSz) != sendSz) + err_sys("SSL_write failed"); + + if (strncmp(send, "quit", 4) == 0) { + fputs("sending server shutdown command: quit!\n", fout); + break; + } + + if (SSL_read(ssl, reply, sizeof(reply)) > 0) + fputs(reply, fout); + } + + SSL_CTX_free(ctx); + SSL_free(ssl); + + fflush(fout); + if (inCreated) fclose(fin); + if (outCreated) fclose(fout); + + ((func_args*)args)->return_code = 0; +} + + +#ifndef NO_MAIN_DRIVER + + int main(int argc, char** argv) + { + func_args args; + + args.argc = argc; + args.argv = argv; + + echoclient_test(&args); + + return args.return_code; + } + +#endif // NO_MAIN_DRIVER diff --git a/extra/yassl/examples/echoclient/echoclient.dsp b/extra/yassl/examples/echoclient/echoclient.dsp new file mode 100644 index 00000000000..52052c6dc44 --- /dev/null +++ b/extra/yassl/examples/echoclient/echoclient.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="echoclient" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=echoclient - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "echoclient.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "echoclient.mak" CFG="echoclient - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "echoclient - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "echoclient - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "echoclient - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /O2 /I "..\..\include" /I "..\..\taocrypt\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "echoclient - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "..\..\include" /I "..\..\taocrypt\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "echoclient - Win32 Release" +# Name "echoclient - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\echoclient.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/extra/yassl/examples/echoclient/input b/extra/yassl/examples/echoclient/input new file mode 100644 index 00000000000..438a592852c --- /dev/null +++ b/extra/yassl/examples/echoclient/input @@ -0,0 +1,93 @@ +/* echoclient.cpp */ + +#include "openssl/ssl.h" /* openssl compatibility test */ +#include +#include + + +#ifdef WIN32 + #include +#else + #include + #include + #include + #include + #include + #include + #include + #include +#endif /* WIN32 */ + + +void err_sys(const char* msg) +{ + fputs("yassl client error: ", stderr); + fputs(msg, stderr); + exit(EXIT_FAILURE); +} + +const char* loopback = "127.0.0.1"; +const short yasslPort = 11111; + +using namespace yaSSL; + + +int main(int argc, char** argv) +{ +#ifdef WIN32 + WSADATA wsd; + WSAStartup(0x0002, &wsd); + int sockfd; +#else + unsigned int sockfd; +#endif /* WIN32 */ + + FILE* fin = stdin; + FILE* fout = stdout; + + if (argc >= 2) fin = fopen(argv[1], "r"); + if (argc >= 3) fout = fopen(argv[2], "w"); + + if (!fin) err_sys("can't open input file"); + if (!fout) err_sys("can't open output file"); + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in servaddr; + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + + servaddr.sin_port = htons(yasslPort); + servaddr.sin_addr.s_addr = inet_addr(loopback); + if (connect(sockfd, (const sockaddr*)&servaddr, sizeof(servaddr)) != 0) + err_sys("tcp connect failed"); + + SSL_METHOD* method = TLSv1_client_method(); + SSL_CTX* ctx = SSL_CTX_new(method); + SSL* ssl = SSL_new(ctx); + + SSL_set_fd(ssl, sockfd); + if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed"); + + char send[1024]; + char reply[1024]; + + while (fgets(send, sizeof(send), fin)) { + + int sendSz = strlen(send) + 1; + if (SSL_write(ssl, send, sendSz) != sendSz) + err_sys("SSL_write failed"); + + if (strncmp(send, "quit", 4) == 0) { + fputs("sending server shutdown command: quit!", fout); + break; + } + + if (SSL_read(ssl, reply, sizeof(reply)) > 0) + fputs(reply, fout); + } + + SSL_CTX_free(ctx); + SSL_free(ssl); + + return 0; +} diff --git a/extra/yassl/examples/echoclient/quit b/extra/yassl/examples/echoclient/quit new file mode 100644 index 00000000000..3db49b3ad12 --- /dev/null +++ b/extra/yassl/examples/echoclient/quit @@ -0,0 +1,2 @@ +quit + diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp new file mode 100644 index 00000000000..14a37a7e175 --- /dev/null +++ b/extra/yassl/examples/echoserver/echoserver.cpp @@ -0,0 +1,126 @@ +/* echoserver.cpp */ + +#include "../../testsuite/test.hpp" + + +#ifndef NO_MAIN_DRIVER + #define ECHO_OUT + + THREAD_RETURN YASSL_API echoserver_test(void*); + int main(int argc, char** argv) + { + func_args args; + + args.argc = argc; + args.argv = argv; + + echoserver_test(&args); + return args.return_code; + } + +#endif // NO_MAIN_DRIVER + + +THREAD_RETURN YASSL_API echoserver_test(void* args) +{ +#ifdef _WIN32 + WSADATA wsd; + WSAStartup(0x0002, &wsd); +#endif + + SOCKET_T sockfd = 0; + int argc = 0; + char** argv = 0; + + set_args(argc, argv, *static_cast(args)); + +#ifdef ECHO_OUT + FILE* fout = stdout; + if (argc >= 2) fout = fopen(argv[1], "w"); + if (!fout) err_sys("can't open output file"); +#endif + + tcp_listen(sockfd); + + SSL_METHOD* method = TLSv1_server_method(); + SSL_CTX* ctx = SSL_CTX_new(method); + + set_serverCerts(ctx); + DH* dh = set_tmpDH(ctx); + + bool shutdown(false); + +#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) + // signal ready to tcp_accept + func_args& server_args = *((func_args*)args); + tcp_ready& ready = *server_args.signal_; + pthread_mutex_lock(&ready.mutex_); + ready.ready_ = true; + pthread_cond_signal(&ready.cond_); + pthread_mutex_unlock(&ready.mutex_); +#endif + + while (!shutdown) { + sockaddr_in client; + socklen_t client_len = sizeof(client); + int clientfd = accept(sockfd, (sockaddr*)&client, &client_len); + if (clientfd == -1) err_sys("tcp accept failed"); + + SSL* ssl = SSL_new(ctx); + SSL_set_fd(ssl, clientfd); + if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed"); + + char command[1024]; + int echoSz(0); + while ( (echoSz = SSL_read(ssl, command, sizeof(command))) > 0) { + + if ( strncmp(command, "quit", 4) == 0) { + printf("client sent quit command: shutting down!\n"); + shutdown = true; + break; + } + else if ( strncmp(command, "GET", 3) == 0) { + char type[] = "HTTP/1.0 200 ok\r\nContent-type:" + " text/html\r\n\r\n"; + char header[] = "\n
\n";
+                char body[]   = "greetings from yaSSL\n";
+                char footer[] = "\r\n\r\n";
+            
+                strncpy(command, type, sizeof(type));
+                echoSz = sizeof(type) - 1;
+
+                strncpy(&command[echoSz], header, sizeof(header));
+                echoSz += sizeof(header) - 1;
+                strncpy(&command[echoSz], body, sizeof(body));
+                echoSz += sizeof(body) - 1;
+                strncpy(&command[echoSz], footer, sizeof(footer));
+                echoSz += sizeof(footer);
+
+                if (SSL_write(ssl, command, echoSz) != echoSz)
+                    err_sys("SSL_write failed");
+                break;
+            }
+            command[echoSz] = 0;
+
+        #ifdef ECHO_OUT
+            fputs(command, fout);
+        #endif
+
+            if (SSL_write(ssl, command, echoSz) != echoSz)
+                err_sys("SSL_write failed");
+        }
+        SSL_free(ssl);
+    }
+
+#ifdef _WIN32
+    closesocket(sockfd);
+#else
+    close(sockfd);
+#endif
+
+    DH_free(dh);
+    SSL_CTX_free(ctx);
+
+    ((func_args*)args)->return_code = 0;
+    return 0;
+}
diff --git a/extra/yassl/examples/echoserver/echoserver.dsp b/extra/yassl/examples/echoserver/echoserver.dsp
new file mode 100644
index 00000000000..21a965b013c
--- /dev/null
+++ b/extra/yassl/examples/echoserver/echoserver.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="echoserver" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=echoserver - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "echoserver.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "echoserver.mak" CFG="echoserver - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "echoserver - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "echoserver - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "echoserver - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "..\..\include" /I "..\..\taocrypt\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "echoserver - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "..\..\include" /I "..\..\taocrypt\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "echoserver - Win32 Release"
+# Name "echoserver - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\echoserver.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp
new file mode 100644
index 00000000000..4d3f121cf2c
--- /dev/null
+++ b/extra/yassl/examples/server/server.cpp
@@ -0,0 +1,73 @@
+/* server.cpp */
+
+
+#include "../../testsuite/test.hpp"
+
+
+THREAD_RETURN YASSL_API server_test(void* args)
+{
+#ifdef _WIN32
+    WSADATA wsd;
+    WSAStartup(0x0002, &wsd);
+#endif
+
+    SOCKET_T sockfd   = 0;
+    int      clientfd = 0;
+    int      argc     = 0;
+    char**   argv     = 0;
+
+    set_args(argc, argv, *static_cast(args));
+    tcp_accept(sockfd, clientfd, *static_cast(args));
+
+#ifdef _WIN32
+    closesocket(sockfd);
+#else
+    close(sockfd);
+#endif
+
+    SSL_METHOD* method = TLSv1_server_method();
+    SSL_CTX*    ctx = SSL_CTX_new(method);
+
+    //SSL_CTX_set_cipher_list(ctx, "RC4-SHA");
+    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
+    set_serverCerts(ctx);
+    DH* dh = set_tmpDH(ctx);
+
+    SSL* ssl = SSL_new(ctx);
+    SSL_set_fd(ssl, clientfd);
+   
+    if (SSL_accept(ssl) != SSL_SUCCESS) err_sys("SSL_accept failed");
+    showPeer(ssl);
+    printf("Using Cipher Suite %s\n", SSL_get_cipher(ssl));
+
+    char command[1024];
+    command[SSL_read(ssl, command, sizeof(command))] = 0;
+    printf("First client command: %s\n", command);
+
+    char msg[] = "I hear you, fa shizzle!";
+    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
+        err_sys("SSL_write failed"); 
+
+    DH_free(dh);
+    SSL_CTX_free(ctx);
+    SSL_free(ssl);
+
+    ((func_args*)args)->return_code = 0;
+    return 0;
+}
+
+
+#ifndef NO_MAIN_DRIVER
+
+    int main(int argc, char** argv)
+    {
+        func_args args;
+
+        args.argc = argc;
+        args.argv = argv;
+
+        server_test(&args);
+        return args.return_code;
+    }
+
+#endif // NO_MAIN_DRIVER
diff --git a/extra/yassl/examples/server/server.dsp b/extra/yassl/examples/server/server.dsp
new file mode 100644
index 00000000000..9c797c54dfe
--- /dev/null
+++ b/extra/yassl/examples/server/server.dsp
@@ -0,0 +1,109 @@
+# Microsoft Developer Studio Project File - Name="server" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=server - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "server.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "server.mak" CFG="server - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "server - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "server - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "server - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "..\..\include" /I "..\..\taocrypt\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "server - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "..\..\include" /I "..\..\taocrypt\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none /nodefaultlib
+
+!ENDIF 
+
+# Begin Target
+
+# Name "server - Win32 Release"
+# Name "server - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\server.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/extra/yassl/include/cert_wrapper.hpp b/extra/yassl/include/cert_wrapper.hpp
index 2381347c27e..2a214c529fd 100644
--- a/extra/yassl/include/cert_wrapper.hpp
+++ b/extra/yassl/include/cert_wrapper.hpp
@@ -83,6 +83,7 @@ class CertManager {
     SignerList   signers_;              // decoded CA keys and names
                                         //    plus verified chained certs
     bool verifyPeer_;
+    bool verifyNone_;                   // no error if verify fails
     bool failNoCert_;
     bool sendVerify_;
 public:
@@ -107,10 +108,12 @@ public:
     uint get_privateKeyLength()    const;
 
     bool verifyPeer() const;
+    bool verifyNone() const;
     bool failNoCert() const;
     bool sendVerify() const;
 
     void setVerifyPeer();
+    void setVerifyNone();
     void setFailNoCert();
     void setSendVerify();
 private:
diff --git a/extra/yassl/include/crypto_wrapper.hpp b/extra/yassl/include/crypto_wrapper.hpp
index ca9d870677e..cb542c25a67 100644
--- a/extra/yassl/include/crypto_wrapper.hpp
+++ b/extra/yassl/include/crypto_wrapper.hpp
@@ -41,8 +41,8 @@
 namespace yaSSL {
 
 
-// Digest policy should implement a get_digest, update, and get sizes for pad and 
-// digest
+// Digest policy should implement a get_digest, update, and get sizes for pad
+// and  digest
 struct Digest : public virtual_base {
     virtual void   get_digest(byte*) = 0;
     virtual void   get_digest(byte*, const byte*, unsigned int) = 0;
@@ -380,7 +380,7 @@ public:
     uint        get_agreedKeyLength() const;
     const byte* get_agreedKey()       const;
     const byte* get_publicKey()       const;
-    void        makeAgreement(const byte*);
+    void        makeAgreement(const byte*, unsigned int);
 
     void        set_sizes(int&, int&, int&) const;
     void        get_parms(byte*, byte*, byte*) const;
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index 8a87196b7ed..b6840d006df 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -23,6 +23,8 @@
  *
  */
 
+
+
 #ifndef yaSSL_openssl_h__
 #define yaSSL_openssl_h__
 
@@ -49,7 +51,7 @@ extern "C" {
     class X509_NAME;
 #else
     typedef struct SSL         SSL;          
-    typedef struct SSL_SESION  SSL_SESSION;
+    typedef struct SSL_SESSION  SSL_SESSION;
     typedef struct SSL_METHOD  SSL_METHOD;
     typedef struct SSL_CTX     SSL_CTX;
     typedef struct SSL_CIPHER  SSL_CIPHER;
@@ -258,6 +260,8 @@ int SSL_pending(SSL*);
 
 
 enum { /* ssl Constants */
+    SSL_BAD_STAT        = -7,
+    SSL_BAD_PATH        = -6,
     SSL_BAD_FILETYPE    = -5,
     SSL_BAD_FILE        = -4,
     SSL_NOT_IMPLEMENTED = -3,
diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp
index 38a9ce3bd25..d2258a93723 100644
--- a/extra/yassl/include/socket_wrapper.hpp
+++ b/extra/yassl/include/socket_wrapper.hpp
@@ -77,7 +77,7 @@ public:
     uint send(const byte* buf, unsigned int len, int flags = 0) const;
     uint receive(byte* buf, unsigned int len, int flags = 0)    const;
 
-    void wait() const;
+    bool wait() const;
 
     void closeSocket();
     void shutDown(int how = SD_SEND);
diff --git a/extra/yassl/include/yassl.hpp b/extra/yassl/include/yassl.hpp
new file mode 100644
index 00000000000..edb8e416eb6
--- /dev/null
+++ b/extra/yassl/include/yassl.hpp
@@ -0,0 +1,88 @@
+/* yassl.hpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/* yaSSL externel header defines yaSSL API
+ */
+
+
+#ifndef yaSSL_EXT_HPP
+#define yaSSL_EXT_HPP
+
+
+namespace yaSSL {
+
+
+#ifdef _WIN32
+    typedef unsigned int SOCKET_T;
+#else
+    typedef int          SOCKET_T;
+#endif
+
+
+class Client {
+public:
+    Client();
+    ~Client();
+
+    // basics
+    int Connect(SOCKET_T);
+    int Write(const void*, int);
+    int Read(void*, int);
+
+    // options
+    void SetCA(const char*);
+    void SetCert(const char*);
+    void SetKey(const char*);
+private:
+    struct ClientImpl;
+    ClientImpl* pimpl_;
+
+    Client(const Client&);              // hide copy
+    Client& operator=(const Client&);   // and assign  
+};
+
+
+class Server {
+public:
+    Server();
+    ~Server();
+
+    // basics
+    int Accept(SOCKET_T);
+    int Write(const void*, int);
+    int Read(void*, int);
+
+    // options
+    void SetCA(const char*);
+    void SetCert(const char*);
+    void SetKey(const char*);
+private:
+    struct ServerImpl;
+    ServerImpl* pimpl_;
+
+    Server(const Server&);              // hide copy
+    Server& operator=(const Server&);   // and assign
+};
+
+
+} // namespace yaSSL
+#endif // yaSSL_EXT_HPP
diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp
index 0b06a37a635..9c12b06e34a 100644
--- a/extra/yassl/include/yassl_error.hpp
+++ b/extra/yassl/include/yassl_error.hpp
@@ -59,6 +59,10 @@ enum YasslError {
 
 
 enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib };
+enum { MAX_ERROR_SZ = 80 };
+
+void SetErrorString(YasslError, char*);
+
 
 // Base class for all yaSSL exceptions
 class Error : public mySTL::runtime_error {
diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp
index 3de58901f8e..2f240b71c03 100644
--- a/extra/yassl/include/yassl_imp.hpp
+++ b/extra/yassl/include/yassl_imp.hpp
@@ -662,7 +662,7 @@ struct Parameters {
     uint8                suites_size_;
     Cipher               suites_[MAX_SUITE_SZ];
     char                 cipher_name_[MAX_SUITE_NAME];
-    char                 cipher_list_[MAX_CIPHER_LIST];
+    char                 cipher_list_[MAX_CIPHERS][MAX_SUITE_NAME];
 
     Parameters(ConnectionEnd, const Ciphers&, ProtocolVersion);
 
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index e75294ad073..935bae582ea 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -77,8 +77,6 @@ enum ServerState {
 
 // combines all states
 class States {
-    enum {MAX_ERROR_SZ = 80 };
-
     RecordLayerState recordLayer_;
     HandShakeState   handshakeLayer_;
     ClientState      clientState_;
@@ -227,7 +225,8 @@ sslFactory& GetSSL_Factory();
 class SSL_METHOD {
     ProtocolVersion version_;
     ConnectionEnd   side_;
-    bool            verifyPeer_;
+    bool            verifyPeer_;    // request or send certificate
+    bool            verifyNone_;    // whether to verify certificate
     bool            failNoCert_;
 public:
     explicit SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv);
@@ -236,9 +235,11 @@ public:
     ConnectionEnd   getSide()    const;
 
     void setVerifyPeer();
+    void setVerifyNone();
     void setFailNoCert();
 
     bool verifyPeer() const;
+    bool verifyNone() const;
     bool failNoCert() const;
 private:
     SSL_METHOD(const SSL_METHOD&);              // hide copy
@@ -331,6 +332,7 @@ public:
     const Stats&      GetStats()    const;
 
     void setVerifyPeer();
+    void setVerifyNone();
     void setFailNoCert();
     bool SetCipherList(const char*);
     bool SetDH(const DH&);
diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp
index 66cc6aa3c68..bfb6467182b 100644
--- a/extra/yassl/include/yassl_types.hpp
+++ b/extra/yassl/include/yassl_types.hpp
@@ -39,32 +39,34 @@ namespace yaSSL {
 void CleanUp();
 
 
-// library allocation
-struct new_t {};      // yaSSL New type
-extern new_t ys;      // pass in parameter
+#ifdef YASSL_PURE_C
 
-} // namespace yaSSL
+    // library allocation
+    struct new_t {};      // yaSSL New type
+    extern new_t ys;      // pass in parameter
 
-void* operator new  (size_t, yaSSL::new_t);
-void* operator new[](size_t, yaSSL::new_t);
+    } // namespace yaSSL
 
-void operator delete  (void*, yaSSL::new_t);
-void operator delete[](void*, yaSSL::new_t);
+    void* operator new  (size_t, yaSSL::new_t);
+    void* operator new[](size_t, yaSSL::new_t);
+
+    void operator delete  (void*, yaSSL::new_t);
+    void operator delete[](void*, yaSSL::new_t);
 
 
-namespace yaSSL {
+    namespace yaSSL {
 
 
-template
-void ysDelete(T* ptr)
-{
+    template
+    void ysDelete(T* ptr)
+    {
     if (ptr) ptr->~T();
     ::operator delete(ptr, yaSSL::ys);
-}
+    }
 
-template
-void ysArrayDelete(T* ptr)
-{
+    template
+    void ysArrayDelete(T* ptr)
+    {
     // can't do array placement destruction since not tracking size in
     // allocation, only allow builtins to use array placement since they
     // don't need destructors called
@@ -72,15 +74,40 @@ void ysArrayDelete(T* ptr)
     (void)sizeof(builtin);
 
     ::operator delete[](ptr, yaSSL::ys);
-}
+    }
 
+    #define NEW_YS new (ys) 
 
-// to resolve compiler generated operator delete on base classes with
-// virtual destructors (when on stack), make sure doesn't get called
-class virtual_base {
-public:
+    // to resolve compiler generated operator delete on base classes with
+    // virtual destructors (when on stack), make sure doesn't get called
+    class virtual_base {
+    public:
     static void operator delete(void*) { assert(0); }
-};
+    };
+
+
+#else   // YASSL_PURE_C
+
+
+    template
+    void ysDelete(T* ptr)
+    {
+        delete ptr;
+    }
+
+    template
+    void ysArrayDelete(T* ptr)
+    {
+        delete[] ptr;
+    }
+
+    #define NEW_YS new
+
+    class virtual_base {};
+
+
+
+#endif // YASSL_PURE_C
 
 
 typedef unsigned char  uint8;
@@ -110,7 +137,7 @@ const int KEY_PREFIX        =   7;  // up to 7 prefix letters for key rounds
 const int FORTEZZA_MAX      = 128;  // Maximum Fortezza Key length
 const int MAX_SUITE_SZ      =  64;  // 32 max suites * sizeof(suite)
 const int MAX_SUITE_NAME    =  48;  // max length of suite name
-const int MAX_CIPHER_LIST   = 512;  // max length of cipher list names
+const int MAX_CIPHERS       =  32;  // max supported ciphers for cipher list
 const int SIZEOF_ENUM       =   1;  // SSL considers an enum 1 byte, not 4
 const int SIZEOF_SENDER     =   4;  // Sender constant, for finished generation
 const int PAD_MD5           =  48;  // pad length 1 and 2 for md5 finished
diff --git a/extra/yassl/mySTL/helpers.hpp b/extra/yassl/mySTL/helpers.hpp
index de825c23fec..5aa14d838b1 100644
--- a/extra/yassl/mySTL/helpers.hpp
+++ b/extra/yassl/mySTL/helpers.hpp
@@ -28,6 +28,9 @@
 #define mySTL_HELPERS_HPP
 
 #include 
+#ifdef _MSC_VER
+    #include 
+#endif
 
 /*
       Workaround for the lack of operator new(size_t, void*)
@@ -43,7 +46,6 @@
 
     typedef Dummy* yassl_pointer;
 
-
 namespace mySTL {
 
 
diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp
index 56d355bea80..3bc6dced887 100644
--- a/extra/yassl/src/buffer.cpp
+++ b/extra/yassl/src/buffer.cpp
@@ -24,6 +24,7 @@
  * with SSL types and sockets
  */
 
+
 #include              // memcpy
 #include "runtime.hpp"
 #include "buffer.hpp"
@@ -63,13 +64,13 @@ input_buffer::input_buffer()
 
 
 input_buffer::input_buffer(uint s) 
-    : size_(0), current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s)
+    : size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s)
 {}
 
 
 // with assign
 input_buffer::input_buffer(uint s, const byte* t, uint len) 
-    : size_(0), current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s) 
+    : size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s) 
 { 
     assign(t, len); 
 }
@@ -85,7 +86,7 @@ input_buffer::~input_buffer()
 void input_buffer::allocate(uint s) 
 { 
     assert(!buffer_);       // find realloc error
-    buffer_ = new (ys) byte[s];
+    buffer_ = NEW_YS byte[s];
     end_ = buffer_ + s; 
 }
 
@@ -97,7 +98,7 @@ byte* input_buffer::get_buffer() const
 }
 
 
-// after a raw write user can set new (ys) size
+// after a raw write user can set NEW_YS size
 // if you know the size before the write use assign()
 void input_buffer::add_size(uint i) 
 { 
@@ -199,13 +200,13 @@ output_buffer::output_buffer()
 
 // with allocate
 output_buffer::output_buffer(uint s) 
-    : current_(0), buffer_(new (ys) byte[s]), end_(buffer_ + s) 
+    : current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s) 
 {}
 
 
 // with assign
 output_buffer::output_buffer(uint s, const byte* t, uint len) 
-    : current_(0), buffer_(new (ys) byte[s]), end_(buffer_+ s) 
+    : current_(0), buffer_(NEW_YS byte[s]), end_(buffer_+ s) 
 { 
     write(t, len); 
 }
@@ -240,7 +241,7 @@ void output_buffer::set_current(uint c)
 void output_buffer::allocate(uint s) 
 { 
     assert(!buffer_);   // find realloc error
-    buffer_ = new (ys) byte[s]; end_ = buffer_ + s; 
+    buffer_ = NEW_YS byte[s]; end_ = buffer_ + s; 
 }
 
 
diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp
index a775c366a92..b98c7faf1d0 100644
--- a/extra/yassl/src/cert_wrapper.cpp
+++ b/extra/yassl/src/cert_wrapper.cpp
@@ -39,7 +39,7 @@
 namespace yaSSL {
 
 
-x509::x509(uint sz) : length_(sz), buffer_(new (ys) opaque[sz]) 
+x509::x509(uint sz) : length_(sz), buffer_(NEW_YS opaque[sz]) 
 {
 }
 
@@ -51,7 +51,7 @@ x509::~x509()
 
 
 x509::x509(const x509& that) : length_(that.length_),
-                               buffer_(new (ys) opaque[length_])
+                               buffer_(NEW_YS opaque[length_])
 {
     memcpy(buffer_, that.buffer_, length_);
 }
@@ -92,7 +92,8 @@ opaque* x509::use_buffer()
 
 //CertManager
 CertManager::CertManager()
-    : peerX509_(0), verifyPeer_(false), failNoCert_(false), sendVerify_(false)
+    : peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false),
+      sendVerify_(false)
 {}
 
 
@@ -114,6 +115,12 @@ bool CertManager::verifyPeer() const
 }
 
 
+bool CertManager::verifyNone() const
+{
+    return verifyNone_;
+}
+
+
 bool CertManager::failNoCert() const
 {
     return failNoCert_;
@@ -132,6 +139,12 @@ void CertManager::setVerifyPeer()
 }
 
 
+void CertManager::setVerifyNone()
+{
+    verifyNone_ = true;
+}
+
+
 void CertManager::setFailNoCert()
 {
     failNoCert_ = true;
@@ -153,7 +166,7 @@ void CertManager::AddPeerCert(x509* x)
 void CertManager::CopySelfCert(const x509* x)
 {
     if (x)
-        list_.push_back(new (ys) x509(*x));
+        list_.push_back(NEW_YS x509(*x));
 }
 
 
@@ -161,11 +174,12 @@ void CertManager::CopySelfCert(const x509* x)
 int CertManager::CopyCaCert(const x509* x)
 {
     TaoCrypt::Source source(x->get_buffer(), x->get_length());
-    TaoCrypt::CertDecoder cert(source, true, &signers_);
+    TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_,
+                               TaoCrypt::CertDecoder::CA);
 
     if (!cert.GetError().What()) {
         const TaoCrypt::PublicKey& key = cert.GetPublicKey();
-        signers_.push_back(new (ys) TaoCrypt::Signer(key.GetKey(), key.size(),
+        signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
                                         cert.GetCommonName(), cert.GetHash()));
     }
     return cert.GetError().What();
@@ -228,13 +242,13 @@ int CertManager::Validate()
 
     while ( count > 1 ) {
         TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
-        TaoCrypt::CertDecoder cert(source, true, &signers_);
+        TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
 
         if (int err = cert.GetError().What())
             return err;
 
         const TaoCrypt::PublicKey& key = cert.GetPublicKey();
-        signers_.push_back(new (ys) TaoCrypt::Signer(key.GetKey(), key.size(),
+        signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(),
                                         cert.GetCommonName(), cert.GetHash()));
         --last;
         --count;
@@ -243,7 +257,7 @@ int CertManager::Validate()
     if (count) {
         // peer's is at the front
         TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
-        TaoCrypt::CertDecoder cert(source, true, &signers_);
+        TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
 
         if (int err = cert.GetError().What())
             return err;
@@ -259,7 +273,7 @@ int CertManager::Validate()
 
         int iSz = cert.GetIssuer() ? strlen(cert.GetIssuer()) + 1 : 0;
         int sSz = cert.GetCommonName() ? strlen(cert.GetCommonName()) + 1 : 0;
-        peerX509_ = new (ys) X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
+        peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
                                   sSz);
     }
     return 0;
diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp
index 80cadd3d722..8859fbdd70f 100644
--- a/extra/yassl/src/crypto_wrapper.cpp
+++ b/extra/yassl/src/crypto_wrapper.cpp
@@ -58,13 +58,13 @@ struct MD5::MD5Impl {
 };
 
 
-MD5::MD5() : pimpl_(new (ys) MD5Impl) {}
+MD5::MD5() : pimpl_(NEW_YS MD5Impl) {}
 
 
 MD5::~MD5() { ysDelete(pimpl_); }
 
 
-MD5::MD5(const MD5& that) : Digest(), pimpl_(new (ys) 
+MD5::MD5(const MD5& that) : Digest(), pimpl_(NEW_YS 
                                              MD5Impl(that.pimpl_->md5_)) {}
 
 
@@ -116,13 +116,13 @@ struct SHA::SHAImpl {
 };
 
 
-SHA::SHA() : pimpl_(new (ys) SHAImpl) {}
+SHA::SHA() : pimpl_(NEW_YS SHAImpl) {}
 
 
 SHA::~SHA() { ysDelete(pimpl_); }
 
 
-SHA::SHA(const SHA& that) : Digest(), pimpl_(new (ys) SHAImpl(that.pimpl_->sha_)) {}
+SHA::SHA(const SHA& that) : Digest(), pimpl_(NEW_YS SHAImpl(that.pimpl_->sha_)) {}
 
 SHA& SHA::operator=(const SHA& that)
 {
@@ -173,13 +173,13 @@ struct RMD::RMDImpl {
 };
 
 
-RMD::RMD() : pimpl_(new (ys) RMDImpl) {}
+RMD::RMD() : pimpl_(NEW_YS RMDImpl) {}
 
 
 RMD::~RMD() { ysDelete(pimpl_); }
 
 
-RMD::RMD(const RMD& that) : Digest(), pimpl_(new (ys) RMDImpl(that.pimpl_->rmd_)) {}
+RMD::RMD(const RMD& that) : Digest(), pimpl_(NEW_YS RMDImpl(that.pimpl_->rmd_)) {}
 
 RMD& RMD::operator=(const RMD& that)
 {
@@ -230,7 +230,7 @@ struct HMAC_MD5::HMAC_MD5Impl {
 
 
 HMAC_MD5::HMAC_MD5(const byte* secret, unsigned int len) 
-    : pimpl_(new (ys) HMAC_MD5Impl) 
+    : pimpl_(NEW_YS HMAC_MD5Impl) 
 {
     pimpl_->mac_.SetKey(secret, len);
 }
@@ -280,7 +280,7 @@ struct HMAC_SHA::HMAC_SHAImpl {
 
 
 HMAC_SHA::HMAC_SHA(const byte* secret, unsigned int len) 
-    : pimpl_(new (ys) HMAC_SHAImpl) 
+    : pimpl_(NEW_YS HMAC_SHAImpl) 
 {
     pimpl_->mac_.SetKey(secret, len);
 }
@@ -331,7 +331,7 @@ struct HMAC_RMD::HMAC_RMDImpl {
 
 
 HMAC_RMD::HMAC_RMD(const byte* secret, unsigned int len) 
-    : pimpl_(new (ys) HMAC_RMDImpl) 
+    : pimpl_(NEW_YS HMAC_RMDImpl) 
 {
     pimpl_->mac_.SetKey(secret, len);
 }
@@ -379,7 +379,7 @@ struct DES::DESImpl {
 };
 
 
-DES::DES() : pimpl_(new (ys) DESImpl) {}
+DES::DES() : pimpl_(NEW_YS DESImpl) {}
 
 DES::~DES() { ysDelete(pimpl_); }
 
@@ -415,7 +415,7 @@ struct DES_EDE::DES_EDEImpl {
 };
 
 
-DES_EDE::DES_EDE() : pimpl_(new (ys) DES_EDEImpl) {}
+DES_EDE::DES_EDE() : pimpl_(NEW_YS DES_EDEImpl) {}
 
 DES_EDE::~DES_EDE() { ysDelete(pimpl_); }
 
@@ -453,7 +453,7 @@ struct RC4::RC4Impl {
 };
 
 
-RC4::RC4() : pimpl_(new (ys) RC4Impl) {}
+RC4::RC4() : pimpl_(NEW_YS RC4Impl) {}
 
 RC4::~RC4() { ysDelete(pimpl_); }
 
@@ -495,7 +495,7 @@ struct AES::AESImpl {
 };
 
 
-AES::AES(unsigned int ks) : pimpl_(new (ys) AESImpl(ks)) {}
+AES::AES(unsigned int ks) : pimpl_(NEW_YS AESImpl(ks)) {}
 
 AES::~AES() { ysDelete(pimpl_); }
 
@@ -536,7 +536,7 @@ struct RandomPool::RandomImpl {
     TaoCrypt::RandomNumberGenerator RNG_;
 };
 
-RandomPool::RandomPool() : pimpl_(new (ys) RandomImpl) {}
+RandomPool::RandomPool() : pimpl_(NEW_YS RandomImpl) {}
 
 RandomPool::~RandomPool() { ysDelete(pimpl_); }
 
@@ -580,7 +580,7 @@ void DSS::DSSImpl::SetPrivate(const byte* key, unsigned int sz)
 
 // Set public or private key
 DSS::DSS(const byte* key, unsigned int sz, bool publicKey) 
-    : pimpl_(new (ys) DSSImpl)
+    : pimpl_(NEW_YS DSSImpl)
 {
     if (publicKey) 
         pimpl_->SetPublic(key, sz);
@@ -651,7 +651,7 @@ void RSA::RSAImpl::SetPrivate(const byte* key, unsigned int sz)
 
 // Set public or private key
 RSA::RSA(const byte* key, unsigned int sz, bool publicKey) 
-    : pimpl_(new (ys) RSAImpl)
+    : pimpl_(NEW_YS RSAImpl)
 {
     if (publicKey) 
         pimpl_->SetPublic(key, sz);
@@ -723,13 +723,13 @@ struct Integer::IntegerImpl {
     explicit IntegerImpl(const TaoCrypt::Integer& i) : int_(i) {}
 };
 
-Integer::Integer() : pimpl_(new (ys) IntegerImpl) {}
+Integer::Integer() : pimpl_(NEW_YS IntegerImpl) {}
 
 Integer::~Integer() { ysDelete(pimpl_); }
 
 
 
-Integer::Integer(const Integer& other) : pimpl_(new (ys) 
+Integer::Integer(const Integer& other) : pimpl_(NEW_YS 
                                                IntegerImpl(other.pimpl_->int_))
 {}
 
@@ -773,9 +773,9 @@ struct DiffieHellman::DHImpl {
 
     void AllocKeys(unsigned int pubSz, unsigned int privSz, unsigned int agrSz)
     {
-        publicKey_  = new (ys) byte[pubSz];
-        privateKey_ = new (ys) byte[privSz];
-        agreedKey_  = new (ys) byte[agrSz];
+        publicKey_  = NEW_YS byte[pubSz];
+        privateKey_ = NEW_YS byte[privSz];
+        agreedKey_  = NEW_YS byte[agrSz];
     }
 };
 
@@ -784,7 +784,7 @@ struct DiffieHellman::DHImpl {
 /*
 // server Side DH, server's view
 DiffieHellman::DiffieHellman(const char* file, const RandomPool& random)
-    : pimpl_(new (ys) DHImpl(random.pimpl_->RNG_))
+    : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
 {
     using namespace TaoCrypt;
     Source source;
@@ -808,12 +808,12 @@ DiffieHellman::DiffieHellman(const char* file, const RandomPool& random)
 DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g,
                              unsigned int gSz, const byte* pub,
                              unsigned int pubSz, const RandomPool& random)
-    : pimpl_(new (ys) DHImpl(random.pimpl_->RNG_))
+    : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
 {
     using TaoCrypt::Integer;
 
     pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref());
-    pimpl_->publicKey_ = new (ys) opaque[pubSz];
+    pimpl_->publicKey_ = NEW_YS opaque[pubSz];
     memcpy(pimpl_->publicKey_, pub, pubSz);
 }
 
@@ -821,7 +821,7 @@ DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g,
 // Server Side DH, server's view
 DiffieHellman::DiffieHellman(const Integer& p, const Integer& g,
                              const RandomPool& random)
-: pimpl_(new (ys) DHImpl(random.pimpl_->RNG_))
+: pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
 {
     using TaoCrypt::Integer;
 
@@ -839,7 +839,7 @@ DiffieHellman::~DiffieHellman() { ysDelete(pimpl_); }
 
 // Client side and view, use server that for p and g
 DiffieHellman::DiffieHellman(const DiffieHellman& that) 
-    : pimpl_(new (ys) DHImpl(*that.pimpl_))
+    : pimpl_(NEW_YS DHImpl(*that.pimpl_))
 {   
     pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
                                                   pimpl_->publicKey_);
@@ -855,9 +855,9 @@ DiffieHellman& DiffieHellman::operator=(const DiffieHellman& that)
 }
 
 
-void DiffieHellman::makeAgreement(const byte* other)
+void DiffieHellman::makeAgreement(const byte* other, unsigned int otherSz)
 {
-    pimpl_->dh_.Agree(pimpl_->agreedKey_, pimpl_->privateKey_, other); 
+    pimpl_->dh_.Agree(pimpl_->agreedKey_, pimpl_->privateKey_, other, otherSz); 
 }
 
 
@@ -960,7 +960,7 @@ x509* PemToDer(const char* fname, CertType type)
     Base64Decoder b64Dec(der);
 
     uint sz = der.size();
-    mySTL::auto_ptr x(new (ys) x509(sz), ysDelete);
+    mySTL::auto_ptr x(NEW_YS x509(sz), ysDelete);
     memcpy(x->use_buffer(), der.get_buffer(), sz);
 
     fclose(file);
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index 16c9bde2003..2603365e41a 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -24,6 +24,8 @@
  * the various handshake messages.
  */
 
+
+
 #include "runtime.hpp"
 #include "handshake.hpp"
 #include "yassl_int.hpp"
@@ -362,9 +364,9 @@ void p_hash(output_buffer& result, const output_buffer& secret,
     if (lastLen) times += 1;
 
     if (hash == md5)
-        hmac.reset(new (ys) HMAC_MD5(secret.get_buffer(), secret.get_size()));
+        hmac.reset(NEW_YS HMAC_MD5(secret.get_buffer(), secret.get_size()));
     else
-        hmac.reset(new (ys) HMAC_SHA(secret.get_buffer(), secret.get_size()));
+        hmac.reset(NEW_YS HMAC_SHA(secret.get_buffer(), secret.get_size()));
                                                                    // A0 = seed
     hmac->get_digest(previous, seed.get_buffer(), seed.get_size());// A1
     uint lastTime = times - 1;
@@ -582,11 +584,11 @@ void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
     MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_;
 
     if (algo == sha)
-        hmac.reset(new (ys) HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN));
+        hmac.reset(NEW_YS HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN));
     else if (algo == rmd)
-        hmac.reset(new (ys) HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN));
+        hmac.reset(NEW_YS HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN));
     else
-        hmac.reset(new (ys) HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN));
+        hmac.reset(NEW_YS HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN));
     
     hmac->update(seq, SEQ_SZ);                                       // seq_num
     inner[0] = content;                                              // type
@@ -603,7 +605,7 @@ void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz,
 void PRF(byte* digest, uint digLen, const byte* secret, uint secLen,
          const byte* label, uint labLen, const byte* seed, uint seedLen)
 {
-    uint half = secLen / 2 + secLen % 2;
+    uint half = (secLen + 1) / 2;
 
     output_buffer md5_half(half);
     output_buffer sha_half(half);
@@ -648,18 +650,19 @@ void build_certHashes(SSL& ssl, Hashes& hashes)
 }
 
 
+
 // do process input requests
 mySTL::auto_ptr
 DoProcessReply(SSL& ssl, mySTL::auto_ptr buffered)
 {
-    ssl.getSocket().wait();                  // wait for input if blocking
-    uint ready = ssl.getSocket().get_ready();
-    if (!ready) {
-      // Nothing to receive after blocking wait => error
+    // wait for input if blocking
+    if (!ssl.getSocket().wait()) {
       ssl.SetError(receive_error);
-      buffered.reset(0);
-      return buffered;
+        buffered.reset(0);
+        return buffered;
     }
+    uint ready = ssl.getSocket().get_ready();
+    if (!ready) return buffered; 
 
     // add buffered data if its there
     uint buffSz = buffered.get() ? buffered.get()->get_size() : 0;
@@ -690,7 +693,7 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr buffered)
         // make sure we have enough input in buffer to process this record
         if (hdr.length_ > buffer.get_remaining()) { 
             uint sz = buffer.get_remaining() + RECORD_HEADER;
-            buffered.reset(new (ys) input_buffer(sz, buffer.get_buffer() +
+            buffered.reset(NEW_YS input_buffer(sz, buffer.get_buffer() +
                            buffer.get_current() - RECORD_HEADER, sz));
             break;
         }
@@ -730,6 +733,7 @@ void processReply(SSL& ssl)
             buffered = tmp;
         else
             break;
+        if (ssl.GetError()) return;
     }
 }
 
@@ -767,7 +771,7 @@ void sendClientKeyExchange(SSL& ssl, BufferOutput buffer)
 
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
     buildHeaders(ssl, hsHeader, rlHeader, ck);
     buildOutput(*out.get(), rlHeader, hsHeader, ck);
     hashHandShake(ssl, *out.get());
@@ -788,7 +792,7 @@ void sendServerKeyExchange(SSL& ssl, BufferOutput buffer)
 
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
     buildHeaders(ssl, hsHeader, rlHeader, sk);
     buildOutput(*out.get(), rlHeader, hsHeader, sk);
     hashHandShake(ssl, *out.get());
@@ -813,7 +817,7 @@ void sendChangeCipher(SSL& ssl, BufferOutput buffer)
     ChangeCipherSpec ccs;
     RecordLayerHeader rlHeader;
     buildHeader(ssl, rlHeader, ccs);
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
     buildOutput(*out.get(), rlHeader, ccs);
    
     if (buffer == buffered)
@@ -830,7 +834,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
 
     Finished fin;
     buildFinished(ssl, fin, side == client_end ? client : server);
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
     cipherFinished(ssl, fin, *out.get());                   // hashes handshake
 
     if (ssl.getSecurity().get_resuming()) {
@@ -914,7 +918,7 @@ void sendServerHello(SSL& ssl, BufferOutput buffer)
     ServerHello       sh(ssl.getSecurity().get_connection().version_);
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
 
     buildServerHello(ssl, sh);
     ssl.set_random(sh.get_random(), server_end);
@@ -937,7 +941,7 @@ void sendServerHelloDone(SSL& ssl, BufferOutput buffer)
     ServerHelloDone   shd;
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
 
     buildHeaders(ssl, hsHeader, rlHeader, shd);
     buildOutput(*out.get(), rlHeader, hsHeader, shd);
@@ -958,7 +962,7 @@ void sendCertificate(SSL& ssl, BufferOutput buffer)
     Certificate       cert(ssl.getCrypto().get_certManager().get_cert());
     RecordLayerHeader rlHeader;
     HandShakeHeader   hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
 
     buildHeaders(ssl, hsHeader, rlHeader, cert);
     buildOutput(*out.get(), rlHeader, hsHeader, cert);
@@ -980,7 +984,7 @@ void sendCertificateRequest(SSL& ssl, BufferOutput buffer)
     request.Build();
     RecordLayerHeader  rlHeader;
     HandShakeHeader    hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
 
     buildHeaders(ssl, hsHeader, rlHeader, request);
     buildOutput(*out.get(), rlHeader, hsHeader, request);
@@ -1002,7 +1006,7 @@ void sendCertificateVerify(SSL& ssl, BufferOutput buffer)
     verify.Build(ssl);
     RecordLayerHeader  rlHeader;
     HandShakeHeader    hsHeader;
-    mySTL::auto_ptr out(new (ys) output_buffer, ysDelete);
+    mySTL::auto_ptr out(NEW_YS output_buffer, ysDelete);
 
     buildHeaders(ssl, hsHeader, rlHeader, verify);
     buildOutput(*out.get(), rlHeader, hsHeader, verify);
diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat
new file mode 100644
index 00000000000..4c79a9c6406
--- /dev/null
+++ b/extra/yassl/src/make.bat
@@ -0,0 +1,27 @@
+# quick and dirty build file for testing different MSDEVs
+setlocal 
+
+set myFLAGS= /I../include /I../mySTL /I../taocrypt/include /W3 /c /ZI
+
+cl %myFLAGS% buffer.cpp
+cl %myFLAGS% cert_wrapper.cpp
+cl %myFLAGS% crypto_wrapper.cpp
+cl %myFLAGS% handshake.cpp
+
+cl %myFLAGS% lock.cpp
+cl %myFLAGS% log.cpp
+cl %myFLAGS% socket_wrapper.cpp
+cl %myFLAGS% ssl.cpp
+
+cl %myFLAGS% template_instnt.cpp
+cl %myFLAGS% timer.cpp
+cl %myFLAGS% yassl.cpp
+cl %myFLAGS% yassl_error.cpp
+
+cl %myFLAGS% yassl_imp.cpp
+cl %myFLAGS% yassl_int.cpp
+
+link.exe -lib /out:yassl.lib buffer.obj cert_wrapper.obj crypto_wrapper.obj handshake.obj lock.obj log.obj socket_wrapper.obj ssl.obj template_instnt.obj timer.obj yassl.obj yassl_error.obj yassl_imp.obj yassl_int.obj
+
+
+
diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
index 285e0dee2e5..c6611803421 100644
--- a/extra/yassl/src/socket_wrapper.cpp
+++ b/extra/yassl/src/socket_wrapper.cpp
@@ -46,9 +46,11 @@
 #ifdef _WIN32
     const int SOCKET_EINVAL = WSAEINVAL;
     const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
+    const int SOCKET_EAGAIN = WSAEWOULDBLOCK;
 #else
     const int SOCKET_EINVAL = EINVAL;
     const int SOCKET_EWOULDBLOCK = EWOULDBLOCK;
+    const int SOCKET_EAGAIN = EAGAIN;
 #endif // _WIN32
 
 
@@ -98,10 +100,10 @@ uint Socket::get_ready() const
     ioctlsocket(socket_, FIONREAD, &ready);
 #else
     /*
-      64-bit Solaris requires the variable passed to
-      FIONREAD be a 32-bit value.
+       64-bit Solaris requires the variable passed to
+       FIONREAD be a 32-bit value.
     */
-    int ready = 0;
+    unsigned int ready = 0;
     ioctl(socket_, FIONREAD, &ready);
 #endif
 
@@ -126,18 +128,24 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags) const
     assert(socket_ != INVALID_SOCKET);
     int recvd = ::recv(socket_, reinterpret_cast(buf), sz, flags);
 
-    if (recvd == -1) 
+    // idea to seperate error from would block by arnetheduck@gmail.com
+    if (recvd == -1) {
+        if (get_lastError() == SOCKET_EWOULDBLOCK || 
+            get_lastError() == SOCKET_EAGAIN)
         return 0;
+    }
+    else if (recvd == 0)
+        return static_cast(-1);
 
     return recvd;
 }
 
 
-// wait if blocking for input, or error
-void Socket::wait() const
+// wait if blocking for input, return false for error
+bool Socket::wait() const
 {
     byte b;
-    receive(&b, 1, MSG_PEEK);
+    return receive(&b, 1, MSG_PEEK) != static_cast(-1);
 }
 
 
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 94e783167b3..1aab14009d3 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -38,6 +38,14 @@
 #include "yassl_int.hpp"
 #include 
 
+#ifdef _WIN32
+    #include     // FindFirstFile etc..
+#else
+    #include   // file helper
+    #include    // stat
+    #include      // opendir
+#endif
+
 
 namespace yaSSL {
 
@@ -52,25 +60,25 @@ SSL_METHOD* SSLv3_method()
 
 SSL_METHOD* SSLv3_server_method()
 {
-    return new (ys) SSL_METHOD(server_end, ProtocolVersion(3,0));
+    return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,0));
 }
 
 
 SSL_METHOD* SSLv3_client_method()
 {
-    return new (ys) SSL_METHOD(client_end, ProtocolVersion(3,0));
+    return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,0));
 }
 
 
 SSL_METHOD* TLSv1_server_method()
 {
-    return new (ys) SSL_METHOD(server_end, ProtocolVersion(3,1));
+    return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1));
 }
 
 
 SSL_METHOD* TLSv1_client_method()
 {
-    return new (ys) SSL_METHOD(client_end, ProtocolVersion(3,1));
+    return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1));
 }
 
 
@@ -83,7 +91,7 @@ SSL_METHOD* SSLv23_server_method()
 
 SSL_CTX* SSL_CTX_new(SSL_METHOD* method)
 {
-    return new (ys) SSL_CTX(method);
+    return NEW_YS SSL_CTX(method);
 }
 
 
@@ -95,7 +103,7 @@ void SSL_CTX_free(SSL_CTX* ctx)
 
 SSL* SSL_new(SSL_CTX* ctx)
 {
-    return new (ys) SSL(ctx);
+    return NEW_YS SSL(ctx);
 }
 
 
@@ -115,7 +123,12 @@ int SSL_set_fd(SSL* ssl, int fd)
 int SSL_connect(SSL* ssl)
 {
     sendClientHello(*ssl);
+    ClientState neededState = ssl->getSecurity().get_resuming() ?
+        serverFinishedComplete : serverHelloDoneComplete;
+    while (ssl->getStates().getClient() < neededState) {
+        if (ssl->GetError()) break;
     processReply(*ssl);
+    }
 
     if(ssl->getCrypto().get_certManager().sendVerify())
         sendCertificate(*ssl);
@@ -130,7 +143,10 @@ int SSL_connect(SSL* ssl)
     sendFinished(*ssl, client_end);
     ssl->flushBuffer();
     if (!ssl->getSecurity().get_resuming())
+        while (ssl->getStates().getClient() < serverFinishedComplete) {
+            if (ssl->GetError()) break;
         processReply(*ssl);
+        }
 
     ssl->verifyState(serverFinishedComplete);
     ssl->useLog().ShowTCP(ssl->getSocket().get_fd());
@@ -171,9 +187,7 @@ int SSL_accept(SSL* ssl)
         sendServerHelloDone(*ssl);
         ssl->flushBuffer();
 
-        // Java Client sends fragmented response
-        while (ssl->getStates().getServer() <
-               clientFinishedComplete) {
+        while (ssl->getStates().getServer() < clientFinishedComplete) {
             if (ssl->GetError()) break;
             processReply(*ssl);
         }
@@ -182,10 +196,7 @@ int SSL_accept(SSL* ssl)
     sendFinished(*ssl, server_end);
     ssl->flushBuffer();
     if (ssl->getSecurity().get_resuming()) {
-
-      // Java Client sends fragmented response
-      while (ssl->getStates().getServer() <
-             clientFinishedComplete) {
+        while (ssl->getStates().getServer() < clientFinishedComplete) {
           if (ssl->GetError()) break;
           processReply(*ssl);
       }
@@ -281,9 +292,15 @@ char* SSL_get_shared_ciphers(SSL* /*ssl*/, char* buf, int len)
 }
 
 
-const char* SSL_get_cipher_list(SSL* ssl, int /*priority */)
+const char* SSL_get_cipher_list(SSL* ssl, int priority)
 {
-    return ssl->getSecurity().get_parms().cipher_list_;
+    if (priority < 0 || priority >= MAX_CIPHERS)
+        return 0;
+
+    if (ssl->getSecurity().get_parms().cipher_list_[priority][0])
+        return ssl->getSecurity().get_parms().cipher_list_[priority];
+
+    return 0;
 }
 
 
@@ -455,7 +472,7 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type)
             fseek(input, 0, SEEK_END);
             long sz = ftell(input);
             rewind(input);
-            x = new (ys) x509(sz); // takes ownership
+            x = NEW_YS x509(sz); // takes ownership
             size_t bytes = fread(x->use_buffer(), sz, 1, input);
             if (bytes != 1) {
                 fclose(input);
@@ -492,16 +509,74 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback /*vc*/)
     if (mode & SSL_VERIFY_PEER)
         ctx->setVerifyPeer();
 
+    if (mode == SSL_VERIFY_NONE)
+        ctx->setVerifyNone();
+
     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
         ctx->setFailNoCert();
 }
 
 
 int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
-                                  const char* /*path*/)
+                                  const char* path)
 {
-    // just files for now
-    return read_file(ctx, file, SSL_FILETYPE_PEM, CA);
+    int       ret = SSL_SUCCESS;
+    const int HALF_PATH = 128;
+
+    if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA);
+
+    if (ret == SSL_SUCCESS && path) {
+        // call read_file for each reqular file in path
+#ifdef _WIN32
+
+        WIN32_FIND_DATA FindFileData;
+        HANDLE hFind;
+
+        char name[MAX_PATH + 1];  // directory specification
+        strncpy(name, path, MAX_PATH - 3);
+        strncat(name, "\\*", 3);
+
+        hFind = FindFirstFile(name, &FindFileData);
+        if (hFind == INVALID_HANDLE_VALUE) return SSL_BAD_PATH;
+
+        do {
+            if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
+                strncpy(name, path, MAX_PATH - 2 - HALF_PATH);
+                strncat(name, "\\", 2);
+                strncat(name, FindFileData.cFileName, HALF_PATH);
+                ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
+            }
+        } while (ret == SSL_SUCCESS && FindNextFile(hFind, &FindFileData));
+
+        FindClose(hFind);
+
+#else   // _WIN32
+
+        const int MAX_PATH = 260;
+
+        DIR* dir = opendir(path);
+        if (!dir) return SSL_BAD_PATH;
+
+        struct dirent* entry;
+        struct stat    buf;
+        char           name[MAX_PATH + 1];
+
+        while (ret == SSL_SUCCESS && (entry = readdir(dir))) {
+            strncpy(name, path, MAX_PATH - 1 - HALF_PATH);
+            strncat(name, "/", 1);
+            strncat(name, entry->d_name, HALF_PATH);
+            if (stat(name, &buf) < 0) return SSL_BAD_STAT;
+     
+            if (S_ISREG(buf.st_mode))
+                ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA);
+        }
+
+        closedir(dir);
+
+#endif
+    }
+
+    return ret;
 }
 
 
@@ -648,13 +723,13 @@ void OpenSSL_add_all_algorithms()  // compatibility only
 {}
 
 
-void SSL_library_init()  // compatibility only
+void SSL_library_init()  // compatiblity only
 {}
 
 
 DH* DH_new(void)
 {
-    DH* dh = new (ys) DH;
+    DH* dh = NEW_YS DH;
     if (dh)
         dh->p = dh->g = 0;
     return dh;
@@ -679,7 +754,7 @@ BIGNUM* BN_bin2bn(const unsigned char* num, int sz, BIGNUM* retVal)
 
     if (!retVal) {
         created = true;
-        bn.reset(new (ys) BIGNUM);
+        bn.reset(NEW_YS BIGNUM);
         retVal = bn.get();
     }
 
@@ -706,12 +781,14 @@ void ERR_print_errors_fp(FILE* /*fp*/)
 }
 
 
-char* ERR_error_string(unsigned long /*err*/, char* buffer)
+char* ERR_error_string(unsigned long errNumber, char* buffer)
 {
-    // TODO:
-    static char* msg = "Not Implemented";
-    if (buffer)
-        return strncpy(buffer, msg, strlen(msg));
+    static char* msg = "Please supply a buffer for error string";
+
+    if (buffer) {
+        SetErrorString(YasslError(errNumber), buffer);
+        return buffer;
+    }
 
     return msg;
 }
@@ -728,14 +805,14 @@ const char* X509_verify_cert_error_string(long /* error */)
 const EVP_MD* EVP_md5(void)
 {
     // TODO: FIX add to some list for destruction
-    return new (ys) MD5;
+    return NEW_YS MD5;
 }
 
 
 const EVP_CIPHER* EVP_des_ede3_cbc(void)
 {
     // TODO: FIX add to some list for destruction
-    return new (ys) DES_EDE;
+    return NEW_YS DES_EDE;
 }
 
 
diff --git a/extra/yassl/src/template_instnt.cpp b/extra/yassl/src/template_instnt.cpp
index c55ca39bec2..5782df213ea 100644
--- a/extra/yassl/src/template_instnt.cpp
+++ b/extra/yassl/src/template_instnt.cpp
@@ -35,13 +35,6 @@
 #include "openssl/ssl.h"
 
 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-#if !defined(USE_CRYPTOPP_LIB)
-namespace TaoCrypt {
-template class HMAC;
-template class HMAC;
-template class HMAC;
-}
-#endif  // USE_CRYPTOPP_LIB
 
 namespace mySTL {
 template class list;
diff --git a/extra/yassl/src/timer.cpp b/extra/yassl/src/timer.cpp
index 8b7d2d17a84..4fe0d3aa4f9 100644
--- a/extra/yassl/src/timer.cpp
+++ b/extra/yassl/src/timer.cpp
@@ -26,17 +26,13 @@
 #include "runtime.hpp"
 #include "timer.hpp"
 
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include 
-#else
-#include 
-#endif
-
 namespace yaSSL {
 
 #ifdef _WIN32
 
+    #define WIN32_LEAN_AND_MEAN
+    #include 
+
     timer_d timer()
     {
         static bool          init(false);
@@ -61,6 +57,8 @@ namespace yaSSL {
 
 #else // _WIN32
 
+    #include 
+
     timer_d timer()
     {
         struct timeval tv;
diff --git a/extra/yassl/src/yassl.cpp b/extra/yassl/src/yassl.cpp
new file mode 100644
index 00000000000..86af12fd448
--- /dev/null
+++ b/extra/yassl/src/yassl.cpp
@@ -0,0 +1,244 @@
+/* yassl.cpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/* yaSSL implements external API
+ */
+
+#include "runtime.hpp"
+#include "yassl.hpp"
+#include "yassl_int.hpp"
+#include "handshake.hpp"
+#include 
+
+#include "openssl/ssl.h"  // get rid of this
+
+
+// yaSSL overloads hide these
+void* operator new[](size_t sz)
+{
+    return ::operator new(sz);
+}
+
+void operator delete[](void* ptr)
+{
+    ::operator delete(ptr);
+}
+
+
+namespace yaSSL {
+
+using mySTL::min;
+
+
+struct Base {
+    SSL_METHOD* method_;
+    SSL_CTX*    ctx_;
+    SSL*        ssl_;
+
+    char*       ca_;
+    char*       cert_;
+    char*       key_;
+
+    DH*         dh_;
+
+    Base() : method_(0), ctx_(0), ssl_(0), ca_(0), cert_(0), key_(0), dh_(0)
+    {}
+
+    ~Base()
+    {
+        if (dh_) DH_free(dh_);
+        delete[] key_;
+        delete[] cert_;
+        delete[] ca_;
+        SSL_CTX_free(ctx_);   // frees method_ too
+        SSL_free(ssl_);
+    }
+};
+
+
+void SetDH(Base&);
+
+void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s)
+{
+    base.method_ = new SSL_METHOD(end, ProtocolVersion(3,1));
+    base.ctx_ =    new SSL_CTX(base.method_);
+
+    if (base.ca_)
+        if (SSL_CTX_load_verify_locations(base.ctx_,
+            base.ca_, 0) != SSL_SUCCESS) assert(0);
+    if (base.cert_)
+        if (SSL_CTX_use_certificate_file(base.ctx_,
+            base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
+    if (base.key_)
+        if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_,
+            SSL_FILETYPE_PEM) != SSL_SUCCESS) assert(0);
+
+    if (end == server_end) SetDH(base);
+
+    base.ssl_ = new SSL(base.ctx_);
+    base.ssl_->useSocket().set_fd(s);
+}
+
+
+void SetDH(Base& base)
+{
+    static unsigned char dh512_p[] =
+    {
+      0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+      0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+      0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+      0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+      0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+      0x47,0x74,0xE8,0x33,
+    };
+
+    static unsigned char dh512_g[] =
+    {
+      0x02,
+    };
+
+    if ( (base.dh_ = DH_new()) ) {
+        base.dh_->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0);
+        base.dh_->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0);
+    }
+    if (!base.dh_->p || !base.dh_->g) {
+        DH_free(base.dh_);
+        base.dh_ = 0;
+    }
+    SSL_CTX_set_tmp_dh(base.ctx_, base.dh_);
+}
+
+
+void NewCopy(char*& dst, const char* src)
+{
+    size_t len = strlen(src) + 1;
+    dst = new char[len];
+
+    strncpy(dst, src, len);
+}
+
+
+// Client Implementation
+struct Client::ClientImpl {
+    Base base_;
+};
+
+
+Client::Client() : pimpl_(new ClientImpl)
+{}
+
+
+Client::~Client() { delete pimpl_; }
+
+
+int Client::Connect(SOCKET_T s)
+{
+    SetUpBase(pimpl_->base_, client_end, s);
+    return SSL_connect(pimpl_->base_.ssl_);
+}
+
+
+int Client::Write(const void* buffer, int sz)
+{
+    return sendData(*pimpl_->base_.ssl_, buffer, sz);
+}
+
+
+int Client::Read(void* buffer, int sz)
+{
+    Data data(min(sz, MAX_RECORD_SIZE), static_cast(buffer));
+    return receiveData(*pimpl_->base_.ssl_, data);
+}
+
+
+void Client::SetCA(const char* name)
+{
+    NewCopy(pimpl_->base_.ca_, name);
+}
+
+
+void Client::SetCert(const char* name)
+{
+    NewCopy(pimpl_->base_.cert_, name);
+}
+
+
+void Client::SetKey(const char* name)
+{
+    NewCopy(pimpl_->base_.key_, name);
+}
+
+
+
+// Server Implementation
+struct Server::ServerImpl {
+    Base base_;
+};
+
+
+Server::Server() : pimpl_(new ServerImpl)
+{}
+
+
+Server::~Server() { delete pimpl_; }
+
+
+int Server::Accept(SOCKET_T s)
+{
+    SetUpBase(pimpl_->base_, server_end, s);
+    return SSL_accept(pimpl_->base_.ssl_);
+}
+
+
+int Server::Write(const void* buffer, int sz)
+{
+    return sendData(*pimpl_->base_.ssl_, buffer, sz);
+}
+
+
+int Server::Read(void* buffer, int sz)
+{
+    Data data(min(sz, MAX_RECORD_SIZE), static_cast(buffer));
+    return receiveData(*pimpl_->base_.ssl_, data);
+}
+
+
+void Server::SetCA(const char* name)
+{
+    NewCopy(pimpl_->base_.ca_, name);
+}
+
+
+void Server::SetCert(const char* name)
+{
+    NewCopy(pimpl_->base_.cert_, name);
+}
+
+
+void Server::SetKey(const char* name)
+{
+    NewCopy(pimpl_->base_.key_, name);
+}
+
+
+
+} // namespace yaSSL
diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp
index c53aef2068d..59113d7438c 100644
--- a/extra/yassl/src/yassl_error.cpp
+++ b/extra/yassl/src/yassl_error.cpp
@@ -25,6 +25,7 @@
 
 #include "runtime.hpp"
 #include "yassl_error.hpp"
+#include "error.hpp"        // TaoCrypt error numbers
 
 namespace yaSSL {
 
@@ -48,6 +49,184 @@ Library Error::get_lib() const
 }
 
 
+void SetErrorString(YasslError error, char* buffer)
+{
+    using namespace TaoCrypt;
+    const int max = MAX_ERROR_SZ;  // shorthand
+
+    switch (error) {
+
+        // yaSSL proper errors
+    case range_error :
+        strncpy(buffer, "buffer index error, out of range", max);
+        break; 
+
+    case realloc_error :
+        strncpy(buffer, "trying to realloc a fixed buffer", max);
+        break; 
+
+    case factory_error : 
+        strncpy(buffer, "unknown factory create request", max);
+        break; 
+
+    case unknown_cipher :
+        strncpy(buffer, "trying to use an unknown cipher", max);
+        break; 
+
+    case prefix_error : 
+        strncpy(buffer, "bad master secret derivation, prefix too big", max);
+        break; 
+
+    case record_layer : 
+        strncpy(buffer, "record layer not ready yet", max);
+        break; 
+        
+    case handshake_layer :
+        strncpy(buffer, "handshake layer not ready yet", max);
+        break; 
+
+    case out_of_order :
+        strncpy(buffer, "handshake message received in wrong order", max);
+        break; 
+
+    case bad_input : 
+        strncpy(buffer, "bad cipher suite input", max);
+        break; 
+
+    case match_error :
+        strncpy(buffer, "unable to match a supported cipher suite", max);
+        break; 
+
+    case no_key_file : 
+        strncpy(buffer, "the server needs a private key file", max);
+        break; 
+
+    case verify_error :
+        strncpy(buffer, "unable to verify peer checksum", max);
+        break; 
+
+    case send_error :
+        strncpy(buffer, "socket layer send error", max);
+        break; 
+
+    case receive_error :
+        strncpy(buffer, "socket layer receive error", max);
+        break; 
+
+    case certificate_error :
+        strncpy(buffer, "unable to proccess cerificate", max);
+        break; 
+
+        // TaoCrypt errors
+    case NO_ERROR :
+        strncpy(buffer, "not in error state", max);
+        break;
+
+    case WINCRYPT_E :
+        strncpy(buffer, "bad wincrypt acquire", max);
+        break;
+
+    case CRYPTGEN_E :
+        strncpy(buffer, "CryptGenRandom error", max);
+        break;
+
+    case OPEN_RAN_E :
+        strncpy(buffer, "unable to use random device", max);
+        break;
+
+    case READ_RAN_E :
+        strncpy(buffer, "unable to use random device", max);
+        break;
+
+    case INTEGER_E :
+        strncpy(buffer, "ASN: bad DER Integer Header", max);
+        break;
+
+    case SEQUENCE_E :
+        strncpy(buffer, "ASN: bad Sequence Header", max);
+        break;
+
+    case SET_E :
+        strncpy(buffer, "ASN: bad Set Header", max);
+        break;
+
+    case VERSION_E :
+        strncpy(buffer, "ASN: version length not 1", max);
+        break;
+
+    case SIG_OID_E :
+        strncpy(buffer, "ASN: signature OID mismatch", max);
+        break;
+
+    case BIT_STR_E :
+        strncpy(buffer, "ASN: bad BitString Header", max);
+        break;
+
+    case UNKNOWN_OID_E :
+        strncpy(buffer, "ASN: unknown key OID type", max);
+        break;
+
+    case OBJECT_ID_E :
+        strncpy(buffer, "ASN: bad Ojbect ID Header", max);
+        break;
+
+    case TAG_NULL_E :
+        strncpy(buffer, "ASN: expected TAG NULL", max);
+        break;
+
+    case EXPECT_0_E :
+        strncpy(buffer, "ASN: expected 0", max);
+        break;
+
+    case OCTET_STR_E :
+        strncpy(buffer, "ASN: bad Octet String Header", max);
+        break;
+
+    case TIME_E :
+        strncpy(buffer, "ASN: bad TIME", max);
+        break;
+
+    case DATE_SZ_E :
+        strncpy(buffer, "ASN: bad Date Size", max);
+        break;
+
+    case SIG_LEN_E :
+        strncpy(buffer, "ASN: bad Signature Length", max);
+        break;
+
+    case UNKOWN_SIG_E :
+        strncpy(buffer, "ASN: unknown signature OID", max);
+        break;
+
+    case UNKOWN_HASH_E :
+        strncpy(buffer, "ASN: unknown hash OID", max);
+        break;
+
+    case DSA_SZ_E :
+        strncpy(buffer, "ASN: bad DSA r or s size", max);
+        break;
+
+    case BEFORE_DATE_E :
+        strncpy(buffer, "ASN: before date in the future", max);
+        break;
+
+    case AFTER_DATE_E :
+        strncpy(buffer, "ASN: after date in the past", max);
+        break;
+
+    case SIG_CONFIRM_E :
+        strncpy(buffer, "ASN: bad self signature confirmation", max);
+        break;
+
+    case SIG_OTHER_E :
+        strncpy(buffer, "ASN: bad other signature confirmation", max);
+        break;
+
+    default :
+        strncpy(buffer, "unknown error number", max);
+    }
+}
+
 
 
 }  // namespace yaSSL
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 1d9db46816b..1d2d5396ea0 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -29,6 +29,7 @@
 #include "asn.hpp"  // provide crypto wrapper??
 
 
+
 namespace yaSSL {
 
 
@@ -111,10 +112,14 @@ void ClientDiffieHellmanPublic::build(SSL& ssl)
     uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same
 
     alloc(keyLength, true);
-    dhClient.makeAgreement(dhServer.get_publicKey());
+    dhClient.makeAgreement(dhServer.get_publicKey(), keyLength);
     c16toa(keyLength, Yc_);
     memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength);
 
+    // because of encoding first byte might be zero, don't use it for preMaster
+    if (*dhClient.get_agreedKey() == 0) 
+        ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1);
+    else
     ssl.set_preMaster(dhClient.get_agreedKey(), keyLength);
 }
 
@@ -134,10 +139,10 @@ void DH_Server::build(SSL& ssl)
     const CertManager& cert = ssl.getCrypto().get_certManager();
     
     if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
-        auth.reset(new (ys) RSA(cert.get_privateKey(),
+        auth.reset(NEW_YS RSA(cert.get_privateKey(),
                    cert.get_privateKeyLength(), false));
     else {
-        auth.reset(new (ys) DSS(cert.get_privateKey(),
+        auth.reset(NEW_YS DSS(cert.get_privateKey(),
                    cert.get_privateKeyLength(), false));
         sigSz += DSS_ENCODED_EXTRA;
     }
@@ -168,7 +173,7 @@ void DH_Server::build(SSL& ssl)
     byte hash[FINISHED_SZ];
     MD5  md5;
     SHA  sha;
-    signature_ = new (ys) byte[sigSz];
+    signature_ = NEW_YS byte[sigSz];
 
     const Connection& conn = ssl.getSecurity().get_connection();
     // md5
@@ -199,7 +204,7 @@ void DH_Server::build(SSL& ssl)
     tmp.write(signature_, sigSz);
 
     // key message
-    keyMessage_ = new (ys) opaque[length_];
+    keyMessage_ = NEW_YS opaque[length_];
     memcpy(keyMessage_, tmp.get_buffer(), tmp.get_size());
 }
 
@@ -253,7 +258,7 @@ opaque* EncryptedPreMasterSecret::get_clientKey() const
 void EncryptedPreMasterSecret::alloc(int sz)
 {
     length_ = sz;
-    secret_ = new (ys) opaque[sz];
+    secret_ = NEW_YS opaque[sz];
 }
 
 
@@ -269,10 +274,14 @@ void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input)
     ato16(tmp, keyLength);
 
     alloc(keyLength);
-    input.read(Yc_, length_);
-    dh.makeAgreement(Yc_);
+    input.read(Yc_, keyLength);
+    dh.makeAgreement(Yc_, keyLength); 
 
-    ssl.set_preMaster(dh.get_agreedKey(), keyLength);
+    // because of encoding, first byte might be 0, don't use for preMaster 
+    if (*dh.get_agreedKey() == 0) 
+        ssl.set_preMaster(dh.get_agreedKey() + 1, dh.get_agreedKeyLength() - 1);
+    else
+        ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength());
     ssl.makeMasterSecret();
 }
 
@@ -303,7 +312,7 @@ opaque* ClientDiffieHellmanPublic::get_clientKey() const
 void ClientDiffieHellmanPublic::alloc(int sz, bool offset) 
 {
     length_ = sz + (offset ? KEY_OFFSET : 0); 
-    Yc_ = new (ys) opaque[length_];
+    Yc_ = NEW_YS opaque[length_];
 }
 
 
@@ -348,7 +357,7 @@ void DH_Server::read(SSL& ssl, input_buffer& input)
     tmp[1] = input[AUTO];
     ato16(tmp, length);
 
-    signature_ = new (ys) byte[length];
+    signature_ = NEW_YS byte[length];
     input.read(signature_, length);
 
     // verify signature
@@ -386,7 +395,7 @@ void DH_Server::read(SSL& ssl, input_buffer& input)
     }
 
     // save input
-    ssl.useCrypto().SetDH(new (ys) DiffieHellman(parms_.get_p(),
+    ssl.useCrypto().SetDH(NEW_YS DiffieHellman(parms_.get_p(),
                parms_.get_pSize(), parms_.get_g(), parms_.get_gSize(),
                parms_.get_pub(), parms_.get_pubSize(),
                ssl.getCrypto().get_random()));
@@ -438,7 +447,7 @@ void Parameters::SetSuites(ProtocolVersion pv)
     int i = 0;
     // available suites, best first
     // when adding more, make sure cipher_names is updated and
-    //      MAX_CIPHER_LIST is big enough
+    //      MAX_CIPHERS is big enough
 
     if (isTLS(pv)) {
         suites_[i++] = 0x00;
@@ -510,13 +519,10 @@ void Parameters::SetCipherNames()
 
     for (int j = 0; j < suites; j++) {
         int index = suites_[j*2 + 1];  // every other suite is suite id
-        int len = strlen(cipher_names[index]);
-        memcpy(&cipher_list_[pos], cipher_names[index], len);
-        pos += len;
-        cipher_list_[pos++] = ':';
+        int len = strlen(cipher_names[index]) + 1;
+        strncpy(cipher_list_[pos++], cipher_names[index], len);
     }
-    if (suites)
-        cipher_list_[--pos] = 0;
+    cipher_list_[pos][0] = 0;
 }
 
 
@@ -928,7 +934,7 @@ void Data::Process(input_buffer& input, SSL& ssl)
     // read data
     if (dataSz) {
         input_buffer* data;
-        ssl.addData(data = new (ys) input_buffer(dataSz));
+        ssl.addData(data = NEW_YS input_buffer(dataSz));
         input.read(data->get_buffer(), dataSz);
         data->add_size(dataSz);
 
@@ -1025,7 +1031,7 @@ void Certificate::Process(input_buffer& input, SSL& ssl)
         c24to32(tmp, cert_sz);
         
         x509* myCert;
-        cm.AddPeerCert(myCert = new (ys) x509(cert_sz));
+        cm.AddPeerCert(myCert = NEW_YS x509(cert_sz));
         input.read(myCert->use_buffer(), myCert->get_length());
 
         list_sz -= cert_sz + CERT_HEADER;
@@ -1111,21 +1117,21 @@ const opaque* ServerDHParams::get_pub() const
 
 opaque* ServerDHParams::alloc_p(int sz)
 {
-    p_ = new (ys) opaque[pSz_ = sz];
+    p_ = NEW_YS opaque[pSz_ = sz];
     return p_;
 }
 
 
 opaque* ServerDHParams::alloc_g(int sz)
 {
-    g_ = new (ys) opaque[gSz_ = sz];
+    g_ = NEW_YS opaque[gSz_ = sz];
     return g_;
 }
 
 
 opaque* ServerDHParams::alloc_pub(int sz)
 {
-    Ys_ = new (ys) opaque[pubSz_ = sz];
+    Ys_ = NEW_YS opaque[pubSz_ = sz];
     return Ys_;
 }
 
@@ -1323,6 +1329,7 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello)
 
     // Compression
     hello.comp_len_ = input[AUTO];
+    while (hello.comp_len_--)  // ignore for now
     hello.compression_methods_ = CompressionMethod(input[AUTO]);
 
     return input;
@@ -1537,7 +1544,7 @@ void CertificateRequest::Build()
     for (int j = 0; j < authCount; j++) {
         int sz = REQUEST_HEADER + MIN_DIS_SIZE;
         DistinguishedName dn;
-        certificate_authorities_.push_back(dn = new (ys) byte[sz]);
+        certificate_authorities_.push_back(dn = NEW_YS byte[sz]);
 
         opaque tmp[REQUEST_HEADER];
         c16toa(MIN_DIS_SIZE, tmp);
@@ -1584,7 +1591,7 @@ input_buffer& operator>>(input_buffer& input, CertificateRequest& request)
         ato16(tmp, dnSz);
         
         DistinguishedName dn;
-        request.certificate_authorities_.push_back(dn = new (ys) 
+        request.certificate_authorities_.push_back(dn = NEW_YS 
                                                   byte[REQUEST_HEADER + dnSz]);
         memcpy(dn, tmp, REQUEST_HEADER);
         input.read(&dn[REQUEST_HEADER], dnSz);
@@ -1630,7 +1637,11 @@ output_buffer& operator<<(output_buffer& output,
 // CertificateRequest processing handler
 void CertificateRequest::Process(input_buffer&, SSL& ssl)
 {
-    ssl.useCrypto().use_certManager().setSendVerify();
+    CertManager& cm = ssl.useCrypto().use_certManager();
+
+    // make sure user provided cert and key before sending and using
+    if (cm.get_cert() && cm.get_privateKey())
+        cm.setSendVerify();
 }
 
 
@@ -1665,7 +1676,7 @@ void CertificateVerify::Build(SSL& ssl)
         RSA rsa(cert.get_privateKey(), cert.get_privateKeyLength(), false);
 
         sz = rsa.get_cipherLength() + VERIFY_HEADER;
-        sig.reset(new (ys) byte[sz]);
+        sig.reset(NEW_YS byte[sz]);
 
         c16toa(sz - VERIFY_HEADER, len);
         memcpy(sig.get(), len, VERIFY_HEADER);
@@ -1676,7 +1687,7 @@ void CertificateVerify::Build(SSL& ssl)
         DSS dss(cert.get_privateKey(), cert.get_privateKeyLength(), false);
 
         sz = DSS_SIG_SZ + DSS_ENCODED_EXTRA + VERIFY_HEADER;
-        sig.reset(new (ys) byte[sz]);
+        sig.reset(NEW_YS byte[sz]);
 
         c16toa(sz - VERIFY_HEADER, len);
         memcpy(sig.get(), len, VERIFY_HEADER);
@@ -1714,7 +1725,7 @@ input_buffer& operator>>(input_buffer& input, CertificateVerify& request)
     ato16(tmp, sz);
     request.set_length(sz);
 
-    request.signature_ = new (ys) byte[sz];
+    request.signature_ = NEW_YS byte[sz];
     input.read(request.signature_, sz);
 
     return input;
@@ -1975,7 +1986,7 @@ Connection::~Connection()
 
 void Connection::AllocPreSecret(uint sz) 
 { 
-    pre_master_secret_ = new (ys) opaque[pre_secret_len_ = sz];
+    pre_master_secret_ = NEW_YS opaque[pre_secret_len_ = sz];
 }
 
 
@@ -2011,35 +2022,35 @@ void Connection::CleanPreMaster()
 
 
 // Create functions for message factory
-Message* CreateCipherSpec() { return new (ys) ChangeCipherSpec; }
-Message* CreateAlert()      { return new (ys) Alert; }
-Message* CreateHandShake()  { return new (ys) HandShakeHeader; }
-Message* CreateData()       { return new (ys) Data; }
+Message* CreateCipherSpec() { return NEW_YS ChangeCipherSpec; }
+Message* CreateAlert()      { return NEW_YS Alert; }
+Message* CreateHandShake()  { return NEW_YS HandShakeHeader; }
+Message* CreateData()       { return NEW_YS Data; }
 
 // Create functions for handshake factory
-HandShakeBase* CreateHelloRequest()       { return new (ys) HelloRequest; }
-HandShakeBase* CreateClientHello()        { return new (ys) ClientHello; }
-HandShakeBase* CreateServerHello()        { return new (ys) ServerHello; }
-HandShakeBase* CreateCertificate()        { return new (ys) Certificate; }
-HandShakeBase* CreateServerKeyExchange()  { return new (ys) ServerKeyExchange;}
-HandShakeBase* CreateCertificateRequest() { return new (ys) 
+HandShakeBase* CreateHelloRequest()       { return NEW_YS HelloRequest; }
+HandShakeBase* CreateClientHello()        { return NEW_YS ClientHello; }
+HandShakeBase* CreateServerHello()        { return NEW_YS ServerHello; }
+HandShakeBase* CreateCertificate()        { return NEW_YS Certificate; }
+HandShakeBase* CreateServerKeyExchange()  { return NEW_YS ServerKeyExchange;}
+HandShakeBase* CreateCertificateRequest() { return NEW_YS 
                                                     CertificateRequest; }
-HandShakeBase* CreateServerHelloDone()    { return new (ys) ServerHelloDone; }
-HandShakeBase* CreateCertificateVerify()  { return new (ys) CertificateVerify;}
-HandShakeBase* CreateClientKeyExchange()  { return new (ys) ClientKeyExchange;}
-HandShakeBase* CreateFinished()           { return new (ys) Finished; }
+HandShakeBase* CreateServerHelloDone()    { return NEW_YS ServerHelloDone; }
+HandShakeBase* CreateCertificateVerify()  { return NEW_YS CertificateVerify;}
+HandShakeBase* CreateClientKeyExchange()  { return NEW_YS ClientKeyExchange;}
+HandShakeBase* CreateFinished()           { return NEW_YS Finished; }
 
 // Create functions for server key exchange factory
-ServerKeyBase* CreateRSAServerKEA()       { return new (ys) RSA_Server; }
-ServerKeyBase* CreateDHServerKEA()        { return new (ys) DH_Server; }
-ServerKeyBase* CreateFortezzaServerKEA()  { return new (ys) Fortezza_Server; }
+ServerKeyBase* CreateRSAServerKEA()       { return NEW_YS RSA_Server; }
+ServerKeyBase* CreateDHServerKEA()        { return NEW_YS DH_Server; }
+ServerKeyBase* CreateFortezzaServerKEA()  { return NEW_YS Fortezza_Server; }
 
 // Create functions for client key exchange factory
-ClientKeyBase* CreateRSAClient()      { return new (ys) 
+ClientKeyBase* CreateRSAClient()      { return NEW_YS 
                                                 EncryptedPreMasterSecret; }
-ClientKeyBase* CreateDHClient()       { return new (ys) 
+ClientKeyBase* CreateDHClient()       { return NEW_YS 
                                                 ClientDiffieHellmanPublic; }
-ClientKeyBase* CreateFortezzaClient() { return new (ys) FortezzaKeys; }
+ClientKeyBase* CreateFortezzaClient() { return NEW_YS FortezzaKeys; }
 
 
 // Constructor calls this to Register compile time callbacks
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 87d990b3506..396461a6ed5 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -31,40 +31,41 @@
 #include "openssl/ssl.h"  // for DH
 
 
-void* operator new(size_t sz, yaSSL::new_t)
-{
 #ifdef YASSL_PURE_C
+
+    void* operator new(size_t sz, yaSSL::new_t)
+    {
     void* ptr = malloc(sz ? sz : 1);
     if (!ptr) abort();
 
     return ptr;
-#else
-    return ::operator new(sz);
-#endif
-}
+    }
 
 
-void operator delete(void* ptr, yaSSL::new_t)
-{
-#ifdef YASSL_PURE_C
+    void operator delete(void* ptr, yaSSL::new_t)
+    {
     if (ptr) free(ptr);
-#else
-    ::operator delete(ptr);
-#endif
-}
+    }
 
 
-void* operator new[](size_t sz, yaSSL::new_t nt)
-{
+    void* operator new[](size_t sz, yaSSL::new_t nt)
+    {
     return ::operator new(sz, nt);
-}
+    }
 
 
-void operator delete[](void* ptr, yaSSL::new_t nt)
-{
+    void operator delete[](void* ptr, yaSSL::new_t nt)
+    {
     ::operator delete(ptr, nt);
-}
+    }
 
+    namespace yaSSL {
+
+        new_t ys;   // for yaSSL library new
+
+    }
+
+#endif // YASSL_PURE_C
 
 
 namespace yaSSL {
@@ -72,7 +73,6 @@ namespace yaSSL {
 
 using mySTL::min;
 
-new_t ys;   // for yaSSL library new
 
 
 
@@ -286,6 +286,8 @@ SSL::SSL(SSL_CTX* ctx)
 
     if (ctx->getMethod()->verifyPeer())
         cm.setVerifyPeer();
+    if (ctx->getMethod()->verifyNone())
+        cm.setVerifyNone();
     if (ctx->getMethod()->failNoCert())
         cm.setFailNoCert();
 
@@ -321,8 +323,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = AES_256_KEY_SZ;
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_256_CBC_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -335,8 +337,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = AES_128_KEY_SZ;
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_128_CBC_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -349,8 +351,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = DES_EDE_KEY_SZ;
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_3DES_EDE_CBC_SHA]
                 , MAX_SUITE_NAME);
         break;
@@ -363,8 +365,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = DES_KEY_SZ;
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES);
         strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_DES_CBC_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -377,8 +379,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = RC4_KEY_SZ;
         parms.iv_size_   = 0;
         parms.cipher_type_ = stream;
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) RC4);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS RC4);
         strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -391,8 +393,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = RC4_KEY_SZ;
         parms.iv_size_   = 0;
         parms.cipher_type_ = stream;
-        crypto_.setDigest(new (ys) MD5);
-        crypto_.setCipher(new (ys) RC4);
+        crypto_.setDigest(NEW_YS MD5);
+        crypto_.setCipher(NEW_YS RC4);
         strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_MD5],
                 MAX_SUITE_NAME);
         break;
@@ -407,8 +409,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES);
         strncpy(parms.cipher_name_, cipher_names[SSL_DHE_RSA_WITH_DES_CBC_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -423,8 +425,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_,
               cipher_names[SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -439,8 +441,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_,
                cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -455,8 +457,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_,
                cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -471,8 +473,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES);
         strncpy(parms.cipher_name_, cipher_names[SSL_DHE_DSS_WITH_DES_CBC_SHA],
                 MAX_SUITE_NAME);
         break;
@@ -487,8 +489,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_,
               cipher_names[SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -503,8 +505,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_,
                cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -519,8 +521,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) SHA);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS SHA);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_,
                cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME);
         break;
@@ -533,8 +535,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = AES_256_KEY_SZ;
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_RSA_WITH_AES_256_CBC_RMD160], MAX_SUITE_NAME);
         break;
@@ -547,8 +549,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = AES_128_KEY_SZ;
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_RSA_WITH_AES_128_CBC_RMD160], MAX_SUITE_NAME);
         break;
@@ -561,8 +563,8 @@ void SSL::set_pending(Cipher suite)
         parms.key_size_  = DES_EDE_KEY_SZ;
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_,
                cipher_names[TLS_RSA_WITH_3DES_EDE_CBC_RMD160], MAX_SUITE_NAME);
         break;
@@ -577,8 +579,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -594,8 +596,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -611,8 +613,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -628,8 +630,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = DES_IV_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) DES_EDE);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS DES_EDE);
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -645,8 +647,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES(AES_256_KEY_SZ));
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ));
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -662,8 +664,8 @@ void SSL::set_pending(Cipher suite)
         parms.iv_size_   = AES_BLOCK_SZ;
         parms.cipher_type_ = block;
         secure_.use_connection().send_server_key_  = true; // eph
-        crypto_.setDigest(new (ys) RMD);
-        crypto_.setCipher(new (ys) AES);
+        crypto_.setDigest(NEW_YS RMD);
+        crypto_.setCipher(NEW_YS AES);
         strncpy(parms.cipher_name_,
                 cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_RMD160],
                 MAX_SUITE_NAME);
@@ -830,7 +832,7 @@ void SSL::deriveKeys()
     int length = 2 * secure_.get_parms().hash_size_ + 
                  2 * secure_.get_parms().key_size_  +
                  2 * secure_.get_parms().iv_size_;
-    int rounds = length / MD5_LEN + ((length % MD5_LEN) ? 1 : 0);
+    int rounds = (length + MD5_LEN - 1 ) / MD5_LEN;
     input_buffer key_data(rounds * MD5_LEN);
 
     opaque sha_output[SHA_LEN];
@@ -1366,17 +1368,16 @@ static Sessions* sessionsInstance = 0;
 Sessions& GetSessions()
 {
     if (!sessionsInstance)
-      sessionsInstance = new (ys) Sessions;
+        sessionsInstance = NEW_YS Sessions;
     return *sessionsInstance;
 }
 
 
 static sslFactory* sslFactoryInstance = 0;
 
-sslFactory& GetSSL_Factory()
-{
+sslFactory& GetSSL_Factory(){
     if (!sslFactoryInstance)
-      sslFactoryInstance = new (ys) sslFactory;
+        sslFactoryInstance = NEW_YS sslFactory;
     return *sslFactoryInstance;
 }
 
@@ -1395,7 +1396,7 @@ typedef Mutex::Lock Lock;
 void Sessions::add(const SSL& ssl) 
 {
     Lock guard(mutex_);
-    list_.push_back(new (ys) SSL_SESSION(ssl, random_));
+    list_.push_back(NEW_YS SSL_SESSION(ssl, random_));
 }
 
 
@@ -1462,7 +1463,8 @@ void Sessions::remove(const opaque* id)
 
 
 SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv) 
-    : version_(pv), side_(ce), verifyPeer_(false), failNoCert_(false) 
+    : version_(pv), side_(ce), verifyPeer_(false), verifyNone_(false),
+      failNoCert_(false) 
 {}
 
 
@@ -1484,6 +1486,12 @@ void SSL_METHOD::setVerifyPeer()
 }
 
 
+void SSL_METHOD::setVerifyNone()
+{
+    verifyNone_ = true;
+}
+
+
 void SSL_METHOD::setFailNoCert()
 {
     failNoCert_ = true;
@@ -1496,6 +1504,12 @@ bool SSL_METHOD::verifyPeer() const
 }
 
 
+bool SSL_METHOD::verifyNone() const
+{
+    return verifyNone_;
+}
+
+
 bool SSL_METHOD::failNoCert() const
 {
     return failNoCert_;
@@ -1572,6 +1586,12 @@ void SSL_CTX::setVerifyPeer()
 }
 
 
+void SSL_CTX::setVerifyNone()
+{
+    method_->setVerifyNone();
+}
+
+
 void SSL_CTX::setFailNoCert()
 {
     method_->setFailNoCert();
@@ -1794,7 +1814,7 @@ void Crypto::SetDH(DiffieHellman* dh)
 void Crypto::SetDH(const DH_Parms& dh)
 {
     if (dh.set_)
-        dh_ = new (ys) DiffieHellman(dh.p_, dh.g_, random_);
+        dh_ = NEW_YS DiffieHellman(dh.p_, dh.g_, random_);
 }
 
 
@@ -1961,7 +1981,7 @@ X509_NAME::X509_NAME(const char* n, size_t sz)
     : name_(0)
 {
     if (sz) {
-        name_ = new (ys) char[sz];
+        name_ = NEW_YS char[sz];
         memcpy(name_, n, sz);
     }
 }
diff --git a/extra/yassl/taocrypt/Makefile.am b/extra/yassl/taocrypt/Makefile.am
index e882f7bafe6..859c704e9d5 100644
--- a/extra/yassl/taocrypt/Makefile.am
+++ b/extra/yassl/taocrypt/Makefile.am
@@ -1,2 +1,2 @@
-SUBDIRS = src
+SUBDIRS = src test benchmark
 EXTRA_DIST = taocrypt.dsw taocrypt.dsp taocrypt.vcproj cmakelists.txt
diff --git a/extra/yassl/taocrypt/benchmark/Makefile.am b/extra/yassl/taocrypt/benchmark/Makefile.am
new file mode 100644
index 00000000000..81200ff7e6a
--- /dev/null
+++ b/extra/yassl/taocrypt/benchmark/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I../include -I../../mySTL
+bin_PROGRAMS       = benchmark
+benchmark_SOURCES  = benchmark.cpp
+benchmark_LDFLAGS  = -L../src
+benchmark_LDADD    = -ltaocrypt
+benchmark_CXXFLAGS = -DYASSL_PURE_C
+benchmark_DEPENDENCIES = ../src/libtaocrypt.la
+EXTRA_DIST = benchmark.dsp rsa1024.der dh1024.der dsa1024.der make.bat
diff --git a/extra/yassl/taocrypt/benchmark/benchmark.cpp b/extra/yassl/taocrypt/benchmark/benchmark.cpp
new file mode 100644
index 00000000000..bb725a90187
--- /dev/null
+++ b/extra/yassl/taocrypt/benchmark/benchmark.cpp
@@ -0,0 +1,440 @@
+// benchmark.cpp
+// TaoCrypt benchmark
+
+#include 
+#include 
+
+#include "runtime.hpp"
+#include "des.hpp"
+#include "aes.hpp"
+#include "twofish.hpp"
+#include "blowfish.hpp"
+#include "arc4.hpp"
+#include "md5.hpp"
+#include "sha.hpp"
+#include "ripemd.hpp"
+#include "rsa.hpp"
+#include "dh.hpp"
+#include "dsa.hpp"
+
+
+using namespace TaoCrypt;
+
+void bench_aes(bool show);
+void bench_des();
+void bench_blowfish();
+void bench_twofish();
+void bench_arc4();
+
+void bench_md5();
+void bench_sha();
+void bench_ripemd();
+
+void bench_rsa();
+void bench_dh();
+void bench_dsa();
+
+double current_time();
+
+
+
+
+int main(int argc, char** argv)
+{
+    bench_aes(false);
+    bench_aes(true);
+    bench_blowfish();
+    bench_twofish();
+    bench_arc4();
+    bench_des();
+    
+    printf("\n");
+
+    bench_md5();
+    bench_sha();
+    bench_ripemd();
+
+    printf("\n");
+    
+    bench_rsa();
+    bench_dh();
+    bench_dsa();
+
+    return 0;
+}
+
+const int megs = 5;  // how much to test
+
+const byte key[] = 
+{
+    0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+    0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
+    0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+};
+
+const byte iv[] = 
+{
+    0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
+    0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+    0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
+    
+};
+
+
+byte plain [1024*1024];
+byte cipher[1024*1024];
+
+
+void bench_des()
+{
+    DES_EDE3_CBC_Encryption enc;
+    enc.SetKey(key, 16, iv);
+
+    double start = current_time();
+
+    for(int i = 0; i < megs; i++)
+        enc.Process(plain, cipher, sizeof(plain));
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("3DES     %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+
+void bench_aes(bool show)
+{
+    AES_CBC_Encryption enc;
+    enc.SetKey(key, 16, iv);
+
+    double start = current_time();
+ 
+    for(int i = 0; i < megs; i++)
+        enc.Process(plain, cipher, sizeof(plain));
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    if (show)
+        printf("AES      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                                 persec);
+}
+
+
+void bench_twofish()
+{
+    Twofish_CBC_Encryption enc;
+    enc.SetKey(key, 16, iv);
+
+    double start = current_time();
+
+    for(int i = 0; i < megs; i++)
+        enc.Process(plain, cipher, sizeof(plain));
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("Twofish  %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                            persec);
+
+}
+
+
+void bench_blowfish()
+{
+    Blowfish_CBC_Encryption enc;
+    enc.SetKey(key, 16, iv);
+
+    double start = current_time();
+
+    for(int i = 0; i < megs; i++)
+        enc.Process(plain, cipher, sizeof(plain));
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("Blowfish %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+
+void bench_arc4()
+{
+    ARC4 enc;
+    enc.SetKey(key, 16);
+
+    double start = current_time();
+
+    for(int i = 0; i < megs; i++)
+        enc.Process(cipher, plain, sizeof(plain));
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("ARC4     %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+
+void bench_md5()
+{
+    MD5 hash;
+    byte digest[MD5::DIGEST_SIZE];
+
+    double start = current_time();
+
+    
+    for(int i = 0; i < megs; i++)
+        hash.Update(plain, sizeof(plain));
+   
+    hash.Final(digest);
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("MD5      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+
+void bench_sha()
+{
+    SHA hash;
+    byte digest[SHA::DIGEST_SIZE];
+
+    double start = current_time();
+
+    
+    for(int i = 0; i < megs; i++)
+        hash.Update(plain, sizeof(plain));
+   
+    hash.Final(digest);
+
+    /*
+    for(int i = 0; i < megs; i++)
+        hash.AsmTransform(plain, 16384);
+    */
+
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("SHA      %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+
+void bench_ripemd()
+{
+    RIPEMD160 hash;
+    byte digest[RIPEMD160::DIGEST_SIZE];
+
+    double start = current_time();
+
+    
+    for(int i = 0; i < megs; i++)
+        hash.Update(plain, sizeof(plain));
+   
+    hash.Final(digest);
+
+    double total = current_time() - start;
+
+    double persec = 1 / total * megs;
+
+    printf("RIPEMD   %d megs took %5.3f seconds, %5.2f MB/s\n", megs, total,
+                                                             persec);
+}
+
+RandomNumberGenerator rng;
+
+void bench_rsa()
+{
+    const int times = 100;
+
+    Source source;
+    FileSource("./rsa1024.der", source);
+
+    if (source.size() == 0) {
+        printf("can't find ./rsa1024.der\n");
+        return;
+    }
+    RSA_PrivateKey priv(source);
+    RSAES_Encryptor enc(priv);
+
+    byte      message[] = "Everyone gets Friday off.";
+    byte      cipher[128];  // for 1024 bit
+    byte      plain[128];   // for 1024 bit
+    const int len = strlen((char*)message);
+    
+    int i;    
+    double start = current_time();
+
+    for (i = 0; i < times; i++)
+        enc.Encrypt(message, len, cipher, rng);
+
+    double total = current_time() - start;
+    double each  = total / times;   // per second
+    double milliEach = each * 1000; // milliseconds
+
+    printf("RSA 1024 encryption took %6.2f milliseconds, avg over %d" 
+           " iterations\n", milliEach, times);
+
+    RSAES_Decryptor dec(priv);
+
+    start = current_time();
+
+    for (i = 0; i < times; i++)
+        dec.Decrypt(cipher, 128, plain, rng);
+
+    total = current_time() - start;
+    each  = total / times;   // per second
+    milliEach = each * 1000; // milliseconds
+
+    printf("RSA 1024 decryption took %6.2f milliseconds, avg over %d" 
+           " iterations\n", milliEach, times);
+}
+
+
+void bench_dh()
+{
+    const int times = 100;
+
+    Source source;
+    FileSource("./dh1024.der", source);
+
+    if (source.size() == 0) {
+        printf("can't find ./dh1024.der\n");
+        return;
+    }
+    DH dh(source);
+
+    byte      pub[128];    // for 1024 bit
+    byte      priv[128];   // for 1024 bit
+    
+    int i;    
+    double start = current_time();
+
+    for (i = 0; i < times; i++)
+        dh.GenerateKeyPair(rng, priv, pub);
+
+    double total = current_time() - start;
+    double each  = total / times;   // per second
+    double milliEach = each * 1000; // milliseconds
+
+    printf("DH  1024 key generation  %6.2f milliseconds, avg over %d" 
+           " iterations\n", milliEach, times);
+
+    DH dh2(dh); 
+    byte      pub2[128];    // for 1024 bit
+    byte      priv2[128];   // for 1024 bit
+    dh2.GenerateKeyPair(rng, priv2, pub2);
+    unsigned char key[256];
+
+    start = current_time();
+
+    for (i = 0; i < times; i++)
+        dh.Agree(key, priv, pub2);
+
+    total = current_time() - start;
+    each  = total / times;      // per second
+    milliEach = each * 1000;   //  in milliseconds
+
+    printf("DH  1024 key agreement   %6.2f milliseconds, avg over %d"
+           " iterations\n", milliEach, times);
+}
+
+void bench_dsa()
+{
+    const int times = 100;
+
+    Source source;
+    FileSource("./dsa1024.der", source);
+
+    if (source.size() == 0) {
+        printf("can't find ./dsa1024.der\n");
+        return;
+    }
+
+    DSA_PrivateKey key(source);
+    DSA_Signer signer(key);
+
+    SHA sha;
+    byte digest[SHA::DIGEST_SIZE];
+    byte signature[40];
+    const char msg[] = "this is the message";
+    sha.Update((byte*)msg, sizeof(msg));
+    sha.Final(digest);
+    
+    int i;    
+    double start = current_time();
+
+    for (i = 0; i < times; i++)
+        signer.Sign(digest, signature, rng); 
+
+    double total = current_time() - start;
+    double each  = total / times;   // per second
+    double milliEach = each * 1000; // milliseconds
+
+    printf("DSA 1024 sign   took     %6.2f milliseconds, avg over %d" 
+           " iterations\n", milliEach, times);
+
+    DSA_Verifier verifier(key);
+
+    start = current_time();
+
+    for (i = 0; i < times; i++)
+        verifier.Verify(digest, signature); 
+
+    total = current_time() - start;
+    each  = total / times;      // per second
+    milliEach = each * 1000;   //  in milliseconds
+
+    printf("DSA 1024 verify took     %6.2f milliseconds, avg over %d"
+           " iterations\n", milliEach, times);
+}
+
+
+
+#ifdef _WIN32
+
+    #define WIN32_LEAN_AND_MEAN
+    #include 
+
+    double current_time()
+    {
+        static bool          init(false);
+        static LARGE_INTEGER freq;
+    
+        if (!init) {
+            QueryPerformanceFrequency(&freq);
+            init = true;
+        }
+
+        LARGE_INTEGER count;
+        QueryPerformanceCounter(&count);
+
+        return static_cast(count.QuadPart) / freq.QuadPart;
+    }
+
+#else
+
+    #include 
+
+    double current_time()
+    {
+        struct timeval tv;
+        gettimeofday(&tv, 0);
+
+        return static_cast(tv.tv_sec) 
+             + static_cast(tv.tv_usec) / 1000000;
+    }
+
+#endif // _WIN32
diff --git a/extra/yassl/taocrypt/benchmark/benchmark.dsp b/extra/yassl/taocrypt/benchmark/benchmark.dsp
new file mode 100644
index 00000000000..ed8fef316bb
--- /dev/null
+++ b/extra/yassl/taocrypt/benchmark/benchmark.dsp
@@ -0,0 +1,101 @@
+# Microsoft Developer Studio Project File - Name="benchmark" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=benchmark - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "benchmark.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "benchmark.mak" CFG="benchmark - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "benchmark - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "benchmark - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "benchmark - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "benchmark___Win32_Release"
+# PROP BASE Intermediate_Dir "benchmark___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\include" /I "..\..\mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "benchmark - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "benchmark___Win32_Debug"
+# PROP BASE Intermediate_Dir "benchmark___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\..\mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "benchmark - Win32 Release"
+# Name "benchmark - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\benchmark.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/extra/yassl/taocrypt/benchmark/dh1024.der b/extra/yassl/taocrypt/benchmark/dh1024.der
new file mode 100644
index 00000000000..1a85d90f3f7
Binary files /dev/null and b/extra/yassl/taocrypt/benchmark/dh1024.der differ
diff --git a/extra/yassl/taocrypt/benchmark/dsa1024.der b/extra/yassl/taocrypt/benchmark/dsa1024.der
new file mode 100644
index 00000000000..1fcb37fad6a
Binary files /dev/null and b/extra/yassl/taocrypt/benchmark/dsa1024.der differ
diff --git a/extra/yassl/taocrypt/benchmark/make.bat b/extra/yassl/taocrypt/benchmark/make.bat
new file mode 100644
index 00000000000..63391578cfa
--- /dev/null
+++ b/extra/yassl/taocrypt/benchmark/make.bat
@@ -0,0 +1,10 @@
+# quick and dirty build file for testing different MSDEVs
+setlocal 
+
+set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2
+#set myFLAGS= /I../include /I../../mySTL /c /W3 
+
+cl %myFLAGS% benchmark.cpp
+
+link.exe  /out:benchmark.exe ../src/taocrypt.lib benchmark.obj
+
diff --git a/extra/yassl/taocrypt/benchmark/rsa1024.der b/extra/yassl/taocrypt/benchmark/rsa1024.der
new file mode 100644
index 00000000000..8fc91814472
Binary files /dev/null and b/extra/yassl/taocrypt/benchmark/rsa1024.der differ
diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp
index b8436d35c5f..e2c1a34b0e3 100644
--- a/extra/yassl/taocrypt/include/aes.hpp
+++ b/extra/yassl/taocrypt/include/aes.hpp
@@ -26,13 +26,13 @@
 #ifndef TAO_CRYPT_AES_HPP
 #define TAO_CRYPT_AES_HPP
 
-#include 
 #include "misc.hpp"
 #include "modes.hpp"
-#include "block.hpp"
+
 
 namespace TaoCrypt {
 
+
 enum { AES_BLOCK_SIZE = 16 };
 
 
@@ -45,32 +45,38 @@ public:
         : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
 
     void Process(byte*, const byte*, word32);
-    void SetKey(const byte* iv, word32 sz, CipherDir fake = ENCRYPTION);
-
-    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+    void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
+    void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
 private:
     CipherDir dir_;
     Mode      mode_;
 
-    static const word32 Te0[256];
-    static const word32 Te1[256];
-    static const word32 Te2[256];
-    static const word32 Te3[256];
-    static const word32 Te4[256];
-
-    static const word32 Td0[256];
-    static const word32 Td1[256];
-    static const word32 Td2[256];
-    static const word32 Td3[256];
-    static const word32 Td4[256];
-
     static const word32 rcon_[];
 
     word32      rounds_;
-    Word32Block key_;
+    word32      key_[60];                        // max size
+
+    static const word32 Te[5][256];
+    static const word32 Td[5][256];
+
+    static const word32* Te0;
+    static const word32* Te1;
+    static const word32* Te2;
+    static const word32* Te3;
+    static const word32* Te4;
+
+    static const word32* Td0;
+    static const word32* Td1;
+    static const word32* Td2;
+    static const word32* Td3;
+    static const word32* Td4;
 
     void encrypt(const byte*, const byte*, byte*) const;
+    void AsmEncrypt(const byte*, byte*, void*) const;
     void decrypt(const byte*, const byte*, byte*) const;
+    void AsmDecrypt(const byte*, byte*, void*) const;
+
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
 
     AES(const AES&);            // hide copy
     AES& operator=(const AES&); // and assign
diff --git a/extra/yassl/taocrypt/include/arc4.hpp b/extra/yassl/taocrypt/include/arc4.hpp
index c919c8ea2ae..c37b89fb294 100644
--- a/extra/yassl/taocrypt/include/arc4.hpp
+++ b/extra/yassl/taocrypt/include/arc4.hpp
@@ -42,6 +42,7 @@ public:
     ARC4() {}
 
     void Process(byte*, const byte*, word32);
+    void AsmProcess(byte*, const byte*, word32);
     void SetKey(const byte*, word32);
 private:
     byte x_;
diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp
index 14fcf22d843..6a1163fbb1c 100644
--- a/extra/yassl/taocrypt/include/asn.hpp
+++ b/extra/yassl/taocrypt/include/asn.hpp
@@ -232,7 +232,12 @@ enum KeyType  { DSAk = 515, RSAk = 645 };     // sums of algo OID
 // an x509v Certificate BER Decoder
 class CertDecoder : public BER_Decoder {
 public:
-    explicit CertDecoder(Source&, bool decode = true, SignerList* = 0);
+    enum DateType { BEFORE, AFTER };   
+    enum NameType { ISSUER, SUBJECT };
+    enum CertType { CA, USER };
+
+    explicit CertDecoder(Source&, bool decode = true, SignerList* sl = 0,
+                         bool noVerify = false, CertType ct = USER);
     ~CertDecoder();
 
     const PublicKey& GetPublicKey()  const { return key_; }
@@ -242,9 +247,6 @@ public:
     const byte*      GetHash()       const { return subjectHash_; }
 
     void DecodeToKey();
-
-    enum DateType { BEFORE, AFTER };   
-    enum NameType { ISSUER, SUBJECT };
 private:
     PublicKey key_;
     word32    certBegin_;               // offset to start of cert
@@ -257,9 +259,10 @@ private:
     byte*     signature_;
     char*     issuer_;                  // CommonName
     char*     subject_;                 // CommonName
+    bool      verify_;                  // Default to yes, but could be off
 
     void   ReadHeader();
-    void   Decode(SignerList*);
+    void   Decode(SignerList*, CertType);
     void   StoreKey();
     void   AddDSA();
     bool   ValidateSelfSignature();
diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp
index ee00ad7487f..4c262e1a540 100644
--- a/extra/yassl/taocrypt/include/block.hpp
+++ b/extra/yassl/taocrypt/include/block.hpp
@@ -99,7 +99,7 @@ public:
         CheckSize(n);
         if (n == 0)
             return 0;
-        return new (tc) T[n];
+        return NEW_TC T[n];
     }
 
     void deallocate(void* p, size_type n)
diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp
new file mode 100644
index 00000000000..7d794a37329
--- /dev/null
+++ b/extra/yassl/taocrypt/include/blowfish.hpp
@@ -0,0 +1,79 @@
+/* blowfish.hpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* blowfish.hpp defines Blowfish
+*/
+
+
+#ifndef TAO_CRYPT_BLOWFISH_HPP
+#define TAO_CRYPT_BLOWFISH_HPP
+
+#include "misc.hpp"
+#include "modes.hpp"
+#include "algorithm.hpp"
+
+namespace TaoCrypt {
+
+enum { BLOWFISH_BLOCK_SIZE = 8 };
+
+
+// Blowfish encryption and decryption, see 
+class Blowfish : public Mode_BASE {
+public:
+    enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 };
+
+    Blowfish(CipherDir DIR, Mode MODE)
+        : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
+
+    void Process(byte*, const byte*, word32);
+    void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
+    void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
+private:
+    CipherDir dir_;
+    Mode      mode_;
+
+	static const word32 p_init_[ROUNDS + 2];
+	static const word32 s_init_[4 * 256];
+
+	word32 pbox_[ROUNDS + 2];
+	word32 sbox_[4 * 256];
+
+    void crypt_block(const word32 in[2], word32 out[2]) const;
+    void AsmProcess(const byte* in, byte* out) const;
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+
+    Blowfish(const Blowfish&);            // hide copy
+    Blowfish& operator=(const Blowfish&); // and assign
+};
+
+
+typedef BlockCipher Blowfish_ECB_Encryption;
+typedef BlockCipher Blowfish_ECB_Decryption;
+
+typedef BlockCipher Blowfish_CBC_Encryption;
+typedef BlockCipher Blowfish_CBC_Decryption;
+
+
+
+} // naemspace
+
+#endif // TAO_CRYPT_BLOWFISH_HPP
+
diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp
index 127b8ddc6d5..e0867b09166 100644
--- a/extra/yassl/taocrypt/include/des.hpp
+++ b/extra/yassl/taocrypt/include/des.hpp
@@ -27,73 +27,87 @@
 #ifndef TAO_CRYPT_DES_HPP
 #define TAO_CRYPT_DES_HPP
 
-#include 
 #include "misc.hpp"
 #include "modes.hpp"
 
 namespace TaoCrypt {
 
-enum { DES_BLOCK_SIZE = 8 };
 
-// Base for all DES types
-class DES_BASE : public Mode_BASE {
+enum { DES_BLOCK_SIZE = 8, DES_KEY_SIZE = 32 };
+
+
+class BasicDES {
 public:
-    enum { BLOCK_SIZE = DES_BLOCK_SIZE, KEY_SIZE = 32, BOXES = 8,
-           BOX_SIZE = 64 };
-
-    DES_BASE(CipherDir DIR, Mode MODE) 
-        : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
-
-    void Process(byte*, const byte*, word32);
+    void SetKey(const byte*, word32, CipherDir dir);
+    void RawProcessBlock(word32&, word32&) const;
 protected:
-    CipherDir dir_;
-    Mode      mode_;
-private:
-    DES_BASE(const DES_BASE&);              // hide copy
-    DES_BASE& operator=(const DES_BASE&);   // and assign
+    word32 k_[DES_KEY_SIZE];
 };
 
 
 // DES 
-class DES : public DES_BASE {
+class DES : public Mode_BASE, public BasicDES {
 public:
-    DES(CipherDir DIR, Mode MODE) : DES_BASE(DIR, MODE) {}
+    DES(CipherDir DIR, Mode MODE) 
+        : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
 
-    void SetKey(const byte*, word32, CipherDir dir);
-    void RawProcessBlock(word32&, word32&) const;
-    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+    void Process(byte*, const byte*, word32);
 private:
-    word32 k_[KEY_SIZE];
+    CipherDir dir_;
+    Mode      mode_;
+
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+
+    DES(const DES&);              // hide copy
+    DES& operator=(const DES&);   // and assign
 };
 
 
 // DES_EDE2
-class DES_EDE2 : public DES_BASE {
+class DES_EDE2 : public Mode_BASE {
 public:
     DES_EDE2(CipherDir DIR, Mode MODE) 
-        : DES_BASE(DIR, MODE), des1_(DIR, MODE), des2_(DIR, MODE) {}
+        : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
 
     void SetKey(const byte*, word32, CipherDir dir);
-    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+    void Process(byte*, const byte*, word32);
 private:
-    DES des1_;
-    DES des2_;
+    CipherDir dir_;
+    Mode      mode_;
+
+    BasicDES  des1_;
+    BasicDES  des2_;
+
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+
+    DES_EDE2(const DES_EDE2&);              // hide copy
+    DES_EDE2& operator=(const DES_EDE2&);   // and assign
 };
 
 
+
 // DES_EDE3
-class DES_EDE3 : public DES_BASE {
+class DES_EDE3 : public Mode_BASE {
 public:
     DES_EDE3(CipherDir DIR, Mode MODE) 
-        : DES_BASE(DIR, MODE), des1_(DIR, MODE), des2_(DIR, MODE),
-                               des3_(DIR, MODE) {}
+        : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
 
     void SetKey(const byte*, word32, CipherDir dir);
-    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+    void SetIV(const byte* iv) { memcpy(r_, iv, DES_BLOCK_SIZE); }
+    void Process(byte*, const byte*, word32);
 private:
-    DES des1_;
-    DES des2_;
-    DES des3_;
+    CipherDir dir_;
+    Mode      mode_;
+
+    BasicDES  des1_;
+    BasicDES  des2_;
+    BasicDES  des3_;
+
+    void AsmProcess(const byte* in, byte* out, void* box) const;
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+
+    DES_EDE3(const DES_EDE3&);              // hide copy
+    DES_EDE3& operator=(const DES_EDE3&);   // and assign
 };
 
 
diff --git a/extra/yassl/taocrypt/include/dh.hpp b/extra/yassl/taocrypt/include/dh.hpp
index 54a1705546b..75a5d6280d3 100644
--- a/extra/yassl/taocrypt/include/dh.hpp
+++ b/extra/yassl/taocrypt/include/dh.hpp
@@ -64,7 +64,7 @@ public:
     }
 
     void GenerateKeyPair(RandomNumberGenerator&, byte*, byte*);
-    void Agree(byte*, const byte*, const byte*);
+    void Agree(byte*, const byte*, const byte*, word32 otherSz = 0);
 
     void SetP(const Integer& p) { p_ = p; }
     void SetG(const Integer& g) { g_ = g; }
diff --git a/extra/yassl/taocrypt/include/hash.hpp b/extra/yassl/taocrypt/include/hash.hpp
index 5c90d01aefe..16112cb644d 100644
--- a/extra/yassl/taocrypt/include/hash.hpp
+++ b/extra/yassl/taocrypt/include/hash.hpp
@@ -57,17 +57,26 @@ public:
     virtual void Update(const byte*, word32);
     virtual void Final(byte*);
 
+    word32  GetBitCountLo() const { return  loLen_ << 3; }
+    word32  GetBitCountHi() const { return (loLen_ >> (8*sizeof(loLen_) - 3)) +
+                                           (hiLen_ << 3); } 
+
     enum { MaxDigestSz = 5, MaxBufferSz = 64 };
 protected:
-    word32  buffLen_;
-    word32  length_;    // in Bits
+    typedef word32 HashLengthType;
+    word32          buffLen_;   // in bytes
+    HashLengthType  loLen_;     // length in bytes
+    HashLengthType  hiLen_;     // length in bytes
     word32  digest_[MaxDigestSz];
     word32  buffer_[MaxBufferSz / sizeof(word32)];
 
     virtual void Transform() = 0;
+
+    void AddLength(word32);
 };
 
 
+
 } // namespace
 
 #endif // TAO_CRYPT_HASH_HPP
diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp
index cf029812ce2..543366afc3a 100644
--- a/extra/yassl/taocrypt/include/hmac.hpp
+++ b/extra/yassl/taocrypt/include/hmac.hpp
@@ -56,12 +56,12 @@ private:
     T     mac_;
 
     // MSVC 6 HACK, gives compiler error if calculated in array
-    enum { HMAC_BSIZE = T::BLOCK_SIZE  / sizeof(word32),
-           HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) };
+    enum { BSIZE = T::BLOCK_SIZE  / sizeof(word32),
+           DSIZE = T::DIGEST_SIZE / sizeof(word32) };
 
-    word32 ip_[HMAC_BSIZE];          // align ipad_ on word32
-    word32 op_[HMAC_BSIZE];          // align opad_ on word32
-    word32 innerH_[HMAC_DSIZE];      // align innerHash_ on word32
+    word32 ip_[BSIZE];          // align ipad_ on word32
+    word32 op_[BSIZE];          // align opad_ on word32
+    word32 innerH_[DSIZE];      // align innerHash_ on word32
 
     void KeyInnerHash();
 
diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp
index d3bd731e2bd..ee83906cfbc 100644
--- a/extra/yassl/taocrypt/include/integer.hpp
+++ b/extra/yassl/taocrypt/include/integer.hpp
@@ -274,7 +274,6 @@ private:
                                Integer& dividend, const Integer& divisor);
     AlignedWordBlock reg_;
     Sign             sign_;
-
 };
 
 inline bool operator==(const Integer& a, const Integer& b) 
diff --git a/extra/yassl/taocrypt/include/kernelc.hpp b/extra/yassl/taocrypt/include/kernelc.hpp
new file mode 100644
index 00000000000..bb74c10ad07
--- /dev/null
+++ b/extra/yassl/taocrypt/include/kernelc.hpp
@@ -0,0 +1,49 @@
+/* kernelc.hpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* kernelc.hpp provides support for C std lib when compiled in kernel mode
+*/
+
+#ifndef TAOCRYPT_KERNELC_HPP
+#define TAOCRYPT_KERNELC_HPP
+
+#include    // get right size_t
+
+// system functions that c++ doesn't like headers for 
+
+extern "C" void* memcpy(void*, const void*, size_t);
+extern "C" void* memset(void*, int, size_t);
+extern "C" void  printk(char *fmt, ...);
+
+#define KERN_ERR "<3>"   /* error conditions */
+
+#if defined(NDEBUG)
+    #define assert(p)  	((void)0)
+#else
+    #define assert(expr)   \
+    if (!(expr))         { \
+         printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
+         #expr,__FILE__,__FUNCTION__,__LINE__); }
+#endif
+
+
+
+#endif // TAOCRYPT_KERNELC_HPP
diff --git a/extra/yassl/taocrypt/include/md5.hpp b/extra/yassl/taocrypt/include/md5.hpp
index 0198daa466e..981f29108fe 100644
--- a/extra/yassl/taocrypt/include/md5.hpp
+++ b/extra/yassl/taocrypt/include/md5.hpp
@@ -45,10 +45,13 @@ public:
     MD5(const MD5&);
     MD5& operator= (const MD5&);
 
+    void Update(const byte*, word32);
+
     void Init();
     void Swap(MD5&);
 private:
     void Transform();
+    void AsmTransform(const byte* data, word32 times);
 };
 
 inline void swap(MD5& a, MD5& b)
diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp
index 26383d4c96b..0808d76ccdf 100644
--- a/extra/yassl/taocrypt/include/misc.hpp
+++ b/extra/yassl/taocrypt/include/misc.hpp
@@ -24,9 +24,15 @@
 #ifndef TAO_CRYPT_MISC_HPP
 #define TAO_CRYPT_MISC_HPP
 
-#include 
-#include 
-#include 
+
+#if !defined(DO_TAOCRYPT_KERNEL_MODE)
+    #include 
+    #include 
+    #include 
+#else
+    #include "kernelc.hpp"
+#endif
+
 #include "types.hpp"
 #include "type_traits.hpp"
 
@@ -39,31 +45,33 @@ namespace TaoCrypt {
 void CleanUp();
 
 
-// library allocation
-struct new_t {};      // TaoCrypt New type
-extern new_t tc;      // pass in parameter
+#ifdef YASSL_PURE_C
 
-} // namespace TaoCrypt
+    // library allocation
+    struct new_t {};      // TaoCrypt New type
+    extern new_t tc;      // pass in parameter
 
-void* operator new  (size_t, TaoCrypt::new_t);
-void* operator new[](size_t, TaoCrypt::new_t);
+    } // namespace TaoCrypt
 
-void operator delete  (void*, TaoCrypt::new_t);
-void operator delete[](void*, TaoCrypt::new_t);
+    void* operator new  (size_t, TaoCrypt::new_t);
+    void* operator new[](size_t, TaoCrypt::new_t);
+
+    void operator delete  (void*, TaoCrypt::new_t);
+    void operator delete[](void*, TaoCrypt::new_t);
 
 
-namespace TaoCrypt {
+    namespace TaoCrypt {
 
-template
-void tcDelete(T* ptr)
-{
+    template
+    void tcDelete(T* ptr)
+    {
     if (ptr) ptr->~T();
     ::operator delete(ptr, TaoCrypt::tc);
-}
+    }
 
-template
-void tcArrayDelete(T* ptr)
-{
+    template
+    void tcArrayDelete(T* ptr)
+    {
     // can't do array placement destruction since not tracking size in
     // allocation, only allow builtins to use array placement since they
     // don't need destructors called
@@ -71,15 +79,39 @@ void tcArrayDelete(T* ptr)
     (void)sizeof(builtin);
 
     ::operator delete[](ptr, TaoCrypt::tc);
-}
+    }
+
+    #define NEW_TC new (TaoCrypt::tc)
 
 
-// to resolve compiler generated operator delete on base classes with
-// virtual destructors (when on stack), make sure doesn't get called
-class virtual_base {
-public:
+    // to resolve compiler generated operator delete on base classes with
+    // virtual destructors (when on stack), make sure doesn't get called
+    class virtual_base {
+    public:
     static void operator delete(void*) { assert(0); }
-};
+    };
+
+#else // YASSL_PURE_C
+
+
+    template
+    void tcDelete(T* ptr)
+    {
+        delete ptr;
+    }
+
+    template
+    void tcArrayDelete(T* ptr)
+    {
+        delete[] ptr;
+    }
+
+    #define NEW_TC new
+
+    class virtual_base {};
+   
+ 
+#endif // YASSL_PURE_C
 
 
 #if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
@@ -100,15 +132,13 @@ public:
     #define TAOCRYPT_DISABLE_X86ASM
 #endif
 
-
-// Disable assmebler when compiling with icc
-// Temporary workaround for bug12717
+// icc problem with -03 and integer, disable for now
 #if defined(__INTEL_COMPILER)
     #define TAOCRYPT_DISABLE_X86ASM
 #endif
 
 
-
+// Turn on ia32 ASM for Big Integer
 // CodeWarrior defines _MSC_VER
 #if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \
    !defined(__MWERKS__) && defined(_M_IX86)) || \
@@ -117,6 +147,20 @@ public:
 #endif
 
 
+// Turn on ia32 ASM for Ciphers and Message Digests
+// Seperate define since these are more complex, use member offsets
+// and user may want to turn off while leaving Big Integer optos on 
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && !defined(DISABLE_TAO_ASM)
+    #define TAO_ASM
+#endif
+
+
+//  Extra word in older vtable implementations, for ASM member offset
+#if defined(__GNUC__) && __GNUC__ < 3
+    #define OLD_GCC_OFFSET
+#endif
+
+
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
 #	define TAOCRYPT_MALLOC_ALIGNMENT_IS_16
 #endif
@@ -437,6 +481,58 @@ inline void ByteReverseIf(T* out, const T* in, word32 bc, ByteOrder order)
 }
 
 
+
+// do Asm Reverse is host is Little and x86asm 
+#ifdef LITTLE_ENDIAN_ORDER
+    #ifdef TAOCRYPT_X86ASM_AVAILABLE
+        #define LittleReverse AsmReverse
+    #else
+        #define LittleReverse ByteReverse
+    #endif
+#else
+    #define LittleReverse
+#endif
+
+
+// do Asm Reverse is host is Big and x86asm 
+#ifdef BIG_ENDIAN_ORDER
+    #ifdef TAOCRYPT_X86ASM_AVAILABLE
+        #define BigReverse AsmReverse
+    #else
+        #define BigReverse ByteReverse
+    #endif
+#else
+    #define BigReverse
+#endif
+
+
+#ifdef TAOCRYPT_X86ASM_AVAILABLE
+
+    // faster than rotate, use bswap
+
+    inline word32 AsmReverse(word32 wd)
+    {
+    #ifdef __GNUC__
+        __asm__ 
+        (
+            "bswap %1"
+            : "=r"(wd)
+            : "0"(wd)
+        );
+    #else
+        __asm 
+        {
+            mov   eax, wd
+            bswap eax
+            mov   wd, eax
+        }
+    #endif
+        return wd;
+    }
+
+#endif 
+
+
 template 
 inline void GetUserKey(ByteOrder order, T* out, word32 outlen, const byte* in,
                        word32 inlen)
diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp
index a23d14db7da..10f336c00eb 100644
--- a/extra/yassl/taocrypt/include/modes.hpp
+++ b/extra/yassl/taocrypt/include/modes.hpp
@@ -26,7 +26,6 @@
 #ifndef TAO_CRYPT_MODES_HPP
 #define TAO_CRYPT_MODES_HPP
 
-#include 
 #include "misc.hpp"
 
 namespace TaoCrypt {
@@ -68,14 +67,8 @@ public:
     }
     virtual ~Mode_BASE() {}
 
-    virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0;
-
-    void ECB_Process(byte*, const byte*, word32);
-    void CBC_Encrypt(byte*, const byte*, word32);
-    void CBC_Decrypt(byte*, const byte*, word32);
-
     void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); }
-private:
+protected:
     int   blockSz_;
     byte* reg_;
     byte* tmp_;
@@ -83,9 +76,15 @@ private:
     word32 r_[MaxBlockSz / sizeof(word32)];  // align reg_ on word32
     word32 t_[MaxBlockSz / sizeof(word32)];  // align tmp_ on word32
 
+    void ECB_Process(byte*, const byte*, word32);
+    void CBC_Encrypt(byte*, const byte*, word32);
+    void CBC_Decrypt(byte*, const byte*, word32);
 
     Mode_BASE(const Mode_BASE&);            // hide copy
     Mode_BASE& operator=(const Mode_BASE&); // and assign
+
+private:
+    virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0;
 };
 
 
diff --git a/extra/yassl/taocrypt/include/pwdbased.hpp b/extra/yassl/taocrypt/include/pwdbased.hpp
new file mode 100644
index 00000000000..f40c48fe026
--- /dev/null
+++ b/extra/yassl/taocrypt/include/pwdbased.hpp
@@ -0,0 +1,93 @@
+/* pwdbased.hpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* pwdbased.hpp defines PBKDF2 from PKCS #5
+*/
+
+
+#ifndef TAO_CRYPT_PWDBASED_HPP
+#define TAO_CRYPT_PWDBASED_HPP
+
+#include 
+#include "misc.hpp"
+#include "block.hpp"
+#include "hmac.hpp"
+
+namespace TaoCrypt {
+
+
+// From PKCS #5, T must be type suitable for HMAC 
+template 
+class PBKDF2_HMAC {
+public:
+    word32 MaxDerivedKeyLength() const { return 0xFFFFFFFFU;} // avoid overflow
+
+    word32 DeriveKey(byte* derived, word32 dLen, const byte* pwd, word32 pLen,
+                     const byte* salt, word32 sLen, word32 iterations) const;
+}; 
+
+
+
+template 
+word32 PBKDF2_HMAC::DeriveKey(byte* derived, word32 dLen, const byte* pwd,
+                                 word32 pLen, const byte* salt, word32 sLen,
+                                 word32 iterations) const
+{
+	assert(dLen <= MaxDerivedKeyLength());
+	assert(iterations > 0);
+
+    ByteBlock buffer(T::DIGEST_SIZE);
+	HMAC   hmac;
+
+    hmac.SetKey(pwd, pLen);
+
+	word32 i = 1;
+
+	while (dLen > 0) {
+		hmac.Update(salt, sLen);
+		word32 j;
+		for (j = 0; j < 4; j++) {
+			byte b = i >> ((3-j)*8);
+			hmac.Update(&b, 1);
+		}
+		hmac.Final(buffer.get_buffer());
+
+		word32 segmentLen = mySTL::min(dLen, buffer.size());
+		memcpy(derived, buffer.get_buffer(), segmentLen);
+
+		for (j = 1; j < iterations; j++) {
+			hmac.Update(buffer.get_buffer(), buffer.size());
+            hmac.Final(buffer.get_buffer());
+			xorbuf(derived, buffer.get_buffer(), segmentLen);
+		}
+		derived += segmentLen;
+		dLen    -= segmentLen;
+		i++;
+	}
+	return iterations;
+}
+
+
+
+
+} // naemspace
+
+#endif // TAO_CRYPT_PWDBASED_HPP
diff --git a/extra/yassl/taocrypt/include/ripemd.hpp b/extra/yassl/taocrypt/include/ripemd.hpp
index 4f8e1fd0386..b72e503f095 100644
--- a/extra/yassl/taocrypt/include/ripemd.hpp
+++ b/extra/yassl/taocrypt/include/ripemd.hpp
@@ -45,10 +45,12 @@ public:
     RIPEMD160(const RIPEMD160&);
     RIPEMD160& operator= (const RIPEMD160&);
 
+    void Update(const byte*, word32);
     void Init();
     void Swap(RIPEMD160&);
 private:
     void Transform();
+    void AsmTransform(const byte* data, word32 times);
 };
 
 inline void swap(RIPEMD160& a, RIPEMD160& b)
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index d9d7877bd93..3a5cf62865a 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -30,7 +30,7 @@
 
 
 #ifdef __sun
-
+ 
 #include 
 
 // Handler for pure virtual functions
@@ -49,7 +49,11 @@ namespace __Crun {
 #if __GNUC__ > 2
 
 extern "C" {
-#include 
+#if !defined(DO_TAOCRYPT_KERNEL_MODE)
+    #include 
+#else
+    #include "kernelc.hpp"
+#endif
 
 /* Disallow inline __cxa_pure_virtual() */
 static int __cxa_pure_virtual() __attribute__((noinline, used));
diff --git a/extra/yassl/taocrypt/include/sha.hpp b/extra/yassl/taocrypt/include/sha.hpp
index b75d9e3f670..3e301a6f0ae 100644
--- a/extra/yassl/taocrypt/include/sha.hpp
+++ b/extra/yassl/taocrypt/include/sha.hpp
@@ -42,6 +42,7 @@ public:
     word32    getDigestSize() const { return DIGEST_SIZE; }
     word32    getPadSize()    const { return PAD_SIZE; }
 
+    void Update(const byte* data, word32 len);
     void Init();
 
     SHA(const SHA&);
@@ -50,6 +51,7 @@ public:
     void Swap(SHA&);
 private:
     void Transform();
+    void AsmTransform(const byte* data, word32 times);
 };
 
 
diff --git a/extra/yassl/taocrypt/include/twofish.hpp b/extra/yassl/taocrypt/include/twofish.hpp
new file mode 100644
index 00000000000..8605221854f
--- /dev/null
+++ b/extra/yassl/taocrypt/include/twofish.hpp
@@ -0,0 +1,86 @@
+/* twofish.hpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* twofish.hpp defines Twofish
+*/
+
+
+#ifndef TAO_CRYPT_TWOFISH_HPP
+#define TAO_CRYPT_TWOFISH_HPP
+
+#include "misc.hpp"
+#include "modes.hpp"
+#include "algorithm.hpp"
+
+namespace TaoCrypt {
+
+enum { TWOFISH_BLOCK_SIZE = 16 };
+
+
+// Twofish encryption and decryption, see 
+class Twofish : public Mode_BASE {
+public:
+    enum { BLOCK_SIZE = TWOFISH_BLOCK_SIZE };
+
+    Twofish(CipherDir DIR, Mode MODE)
+        : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {}
+
+    void Process(byte*, const byte*, word32);
+    void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION);
+    void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); }
+private:
+    CipherDir dir_;
+    Mode      mode_;
+
+	static const byte     q_[2][256];
+	static const word32 mds_[4][256];
+
+	word32 k_[40];
+	word32 s_[4][256];
+
+	static word32 h0(word32 x, const word32 *key, unsigned int kLen);
+	static word32 h(word32 x, const word32 *key, unsigned int kLen);
+
+    void ProcessAndXorBlock(const byte*, const byte*, byte*) const;
+
+    void encrypt(const byte*, const byte*, byte*) const;
+    void decrypt(const byte*, const byte*, byte*) const;
+
+    void AsmEncrypt(const byte* inBlock, byte* outBlock) const;
+    void AsmDecrypt(const byte* inBlock, byte* outBlock) const;
+
+    Twofish(const Twofish&);            // hide copy
+    Twofish& operator=(const Twofish&); // and assign
+};
+
+
+typedef BlockCipher Twofish_ECB_Encryption;
+typedef BlockCipher Twofish_ECB_Decryption;
+
+typedef BlockCipher Twofish_CBC_Encryption;
+typedef BlockCipher Twofish_CBC_Decryption;
+
+
+
+} // naemspace
+
+#endif // TAO_CRYPT_TWOFISH_HPP
+
diff --git a/extra/yassl/taocrypt/include/types.hpp b/extra/yassl/taocrypt/include/types.hpp
index db9c3792bbd..a2453a994fb 100644
--- a/extra/yassl/taocrypt/include/types.hpp
+++ b/extra/yassl/taocrypt/include/types.hpp
@@ -61,10 +61,11 @@ typedef unsigned int   word32;
 
 // compilers we've found 64-bit multiply insructions for
 #if defined(__GNUC__) || defined(_MSC_VER) || defined(__DECCXX)
-#if !(defined(__ICC) || defined(__INTEL_COMPILER))
+    #if !(defined(__ICC) || defined(__INTEL_COMPILER))
     #define HAVE_64_MULTIPLY
+    #endif
 #endif
-#endif
+
     
 #if defined(HAVE_64_MULTIPLY) && (defined(__alpha__) || defined(__ia64__) \
     || defined(_ARCH_PPC64) || defined(__mips64)  || defined(__x86_64__)) 
diff --git a/extra/yassl/taocrypt/src/Makefile.am b/extra/yassl/taocrypt/src/Makefile.am
index d89fa95a940..d3e72346110 100644
--- a/extra/yassl/taocrypt/src/Makefile.am
+++ b/extra/yassl/taocrypt/src/Makefile.am
@@ -2,10 +2,12 @@ INCLUDES = -I../include -I../../mySTL
 
 noinst_LTLIBRARIES = libtaocrypt.la
 
-libtaocrypt_la_SOURCES  = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \
-	coding.cpp dh.cpp des.cpp dsa.cpp file.cpp hash.cpp \
-	md2.cpp md5.cpp misc.cpp random.cpp ripemd.cpp rsa.cpp sha.cpp \
-	template_instnt.cpp integer.cpp
+libtaocrypt_la_SOURCES  = aes.cpp aestables.cpp algebra.cpp arc4.cpp \
+        asn.cpp bftables.cpp blowfish.cpp coding.cpp des.cpp dh.cpp \
+        dsa.cpp file.cpp hash.cpp integer.cpp md2.cpp md5.cpp misc.cpp \
+        random.cpp ripemd.cpp rsa.cpp sha.cpp template_instnt.cpp \
+        tftables.cpp twofish.cpp
+
 libtaocrypt_la_CXXFLAGS = @yassl_taocrypt_extra_cxxflags@ -DYASSL_PURE_C
 
 EXTRA_DIST = $(wildcard ../include/*.hpp)
diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp
index 09cf28a40b0..e737af33df3 100644
--- a/extra/yassl/taocrypt/src/aes.cpp
+++ b/extra/yassl/taocrypt/src/aes.cpp
@@ -19,15 +19,28 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-/* based on Wei Dai's aes.cpp from CryptoPP */
+/* C++ based on Wei Dai's aes.cpp from CryptoPP */
+/* x86 asm original */
+
+#if defined(TAOCRYPT_KERNEL_MODE)
+    #define DO_TAOCRYPT_KERNEL_MODE
+#endif                                  // only some modules now support this
 
 #include "runtime.hpp"
 #include "aes.hpp"
 
 
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_AES_ASM
+#endif
+
+
 namespace TaoCrypt {
 
 
+#if !defined(DO_AES_ASM)
+
+// Generic Version
 void AES::Process(byte* out, const byte* in, word32 sz)
 {
     if (mode_ == ECB)
@@ -39,6 +52,52 @@ void AES::Process(byte* out, const byte* in, word32 sz)
             CBC_Decrypt(out, in, sz);
 }
 
+#else
+
+// ia32 optimized version
+void AES::Process(byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / BLOCK_SIZE;
+
+    if (mode_ == ECB)
+        while (blocks--) {
+            if (dir_ == ENCRYPTION)
+                AsmEncrypt(in, out, (void*)Te0);
+            else
+                AsmDecrypt(in, out, (void*)Td0);               
+            out += BLOCK_SIZE;
+            in  += BLOCK_SIZE;
+        }
+    else if (mode_ == CBC)    
+        if (dir_ == ENCRYPTION)
+            while (blocks--) {
+                r_[0] ^= *(word32*)in;
+                r_[1] ^= *(word32*)(in +  4);
+                r_[2] ^= *(word32*)(in +  8);
+                r_[3] ^= *(word32*)(in + 12);
+
+                AsmEncrypt((byte*)r_, (byte*)r_, (void*)Te0);
+
+                memcpy(out, r_, BLOCK_SIZE);
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+        else
+            while (blocks--) {
+                AsmDecrypt(in, out, (void*)Td0);
+                
+                *(word32*)out        ^= r_[0];
+                *(word32*)(out +  4) ^= r_[1];
+                *(word32*)(out +  8) ^= r_[2];
+                *(word32*)(out + 12) ^= r_[3];
+
+                memcpy(r_, in, BLOCK_SIZE);
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+}
+
+#endif // DO_AES_ASM
 
 
 void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
@@ -46,9 +105,8 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
     assert( (keylen == 16) || (keylen == 24) || (keylen == 32) );
 
     rounds_ = keylen/4 + 6;
-    key_.New(4*(rounds_+1));
 
-    word32 temp, *rk = key_.get_buffer();
+    word32 temp, *rk = key_;
     unsigned int i=0;
 
     GetUserKey(BigEndianOrder, rk, keylen/4, userKey, keylen);
@@ -128,7 +186,7 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
     if (dir_ == DECRYPTION)
     {
         unsigned int i, j;
-        rk = key_.get_buffer();
+        rk = key_;
 
         /* invert the order of the round keys: */
         for (i = 0, j = 4*rounds_; i < j; i += 4, j -= 4) {
@@ -166,8 +224,6 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
 }
 
 
-typedef BlockGetAndPut gpBlock;
-
 void AES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const
 {
     if (dir_ == ENCRYPTION)
@@ -177,12 +233,16 @@ void AES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const
 }
 
 
+typedef BlockGetAndPut gpBlock;
+
+	
 void AES::encrypt(const byte* inBlock, const byte* xorBlock,
                   byte* outBlock) const
 {
-    word32 s0, s1, s2, s3, t0, t1, t2, t3;
-    const word32 *rk = key_.get_buffer();
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
 
+    const word32 *rk = key_;
     /*
      * map byte array block to cipher state
      * and add initial round key:
@@ -192,9 +252,11 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
     s1 ^= rk[1];
     s2 ^= rk[2];
     s3 ^= rk[3];
+   
     /*
      * Nr - 1 full rounds:
      */
+
     unsigned int r = rounds_ >> 1;
     for (;;) {
         t0 =
@@ -252,6 +314,7 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
             Te3[GETBYTE(t2, 0)] ^
             rk[3];
     }
+
     /*
      * apply last round and
      * map cipher state to byte array block:
@@ -282,16 +345,17 @@ void AES::encrypt(const byte* inBlock, const byte* xorBlock,
         (Te4[GETBYTE(t2, 0)] & 0x000000ff) ^
         rk[3];
 
-    gpBlock::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
 
+    gpBlock::Put(xorBlock, outBlock)(s0)(s1)(s2)(s3);
 }
 
 
 void AES::decrypt(const byte* inBlock, const byte* xorBlock,
                   byte* outBlock) const
 {
-    word32 s0, s1, s2, s3, t0, t1, t2, t3;
-    const word32* rk = key_.get_buffer();
+    word32 s0, s1, s2, s3;
+    word32 t0, t1, t2, t3;
+    const word32* rk = key_;
 
     /*
      * map byte array block to cipher state
@@ -302,9 +366,11 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
     s1 ^= rk[1];
     s2 ^= rk[2];
     s3 ^= rk[3];
+
     /*
      * Nr - 1 full rounds:
      */
+
     unsigned int r = rounds_ >> 1;
     for (;;) {
         t0 =
@@ -395,6 +461,1371 @@ void AES::decrypt(const byte* inBlock, const byte* xorBlock,
 }
 
 
+#if defined(DO_AES_ASM)
+    #ifdef __GNUC__
+        #define AS1(x)    asm(#x);
+        #define AS2(x, y) asm(#x ", " #y);
+
+        #define PROLOG()  \
+            asm(".intel_syntax noprefix"); \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    sub   esp, 4                        )   \
+            AS2(    movd  mm7, ebp                      )   \
+            AS2(    mov   [ebp - 4], esi                )   \
+            AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+            AS2(    mov   esi, DWORD PTR [ebp + 12]     )   \
+            AS2(    mov   ebp, DWORD PTR [ebp + 20]     )
+
+        #define EPILOG()  \
+            AS2(    mov  esi, [ebp - 4]             )   \
+            AS2(    mov  esp, ebp                   )   \
+            AS2(    movd ebx, mm4                   )   \
+            AS2(    movd edi, mm3                   )   \
+            AS1(    emms                            )   \
+            asm(".att_syntax");
+    #else
+        #define AS1(x)    __asm x
+        #define AS2(x, y) __asm x, y
+
+        #define PROLOG() \
+            AS1(    push  ebp                           )   \
+            AS2(    mov   ebp, esp                      )   \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    sub   esp, 4                        )   \
+            AS2(    movd  mm7, ebp                      )   \
+            AS2(    mov   [ebp - 4], esi                )   \
+            AS2(    mov   esi, DWORD PTR [ebp +  8]     )   \
+            AS2(    mov   ebp, DWORD PTR [ebp + 16]     )
+
+        // ebp is restored at end
+        #define EPILOG()  \
+            AS2(    mov   esi, [ebp - 4]                )   \
+            AS2(    movd  ebx, mm4                      )   \
+            AS2(    movd  edi, mm3                      )   \
+            AS2(    mov   esp, ebp                      )   \
+            AS1(    pop   ebp                           )   \
+            AS1(    emms                                )   \
+            AS1(    ret   12                            )
+            
+            
+    #endif
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void AES::AsmEncrypt(const byte* inBlock, byte* outBlock, void* boxes) const
+{
+
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    mov   edx, DWORD PTR [ecx + 60]     )   // rounds
+        AS2(    lea   edi, [ecx + 64]               )   // rk
+    #else
+        AS2(    mov   edx, DWORD PTR [ecx + 56]     )   // rounds
+        AS2(    lea   edi, [ecx + 60]               )   // rk
+    #endif
+
+    AS1(    dec   edx                           )
+    AS2(    movd  mm6, edi                      )   // save rk
+    AS2(    movd  mm5, edx                      )   // save rounds
+  
+    AS2(    mov   eax, DWORD PTR [esi]                                  )
+    AS2(    mov   ebx, DWORD PTR [esi + 4]                              )
+    AS2(    mov   ecx, DWORD PTR [esi + 8]                              )
+    AS2(    mov   edx, DWORD PTR [esi + 12]                             )
+
+    AS1(    bswap eax                                                   )
+    AS1(    bswap ebx                                                   )
+    AS1(    bswap ecx                                                   )
+    AS1(    bswap edx                                                   )
+
+    AS2(    xor   eax, DWORD PTR [edi]               )   // s0
+    AS2(    xor   ebx, DWORD PTR [edi +  4]          )   // s1
+    AS2(    xor   ecx, DWORD PTR [edi +  8]          )   // s2
+    AS2(    xor   edx, DWORD PTR [edi + 12]          )   // s3
+
+    AS1(loop1:                                                          )
+            /* Put0 (mm0) =  
+                Te0[get0,rs 24] ^
+                Te1[get1,rs 16] ^
+                Te2[get2,rs  8] ^
+                Te3[get3,rs  0]
+            */
+       
+    AS2(    mov   esi, eax                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+                                                    
+    AS2(    mov   edi, ebx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, ch                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, dl                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm0, esi                                              )
+
+             /* Put1 (mm1) =  
+                Te0[get1,rs 24] ^
+                Te1[get2,rs 16] ^
+                Te2[get3,rs  8] ^
+                Te3[get0,rs  0]
+            */
+
+    AS2(    mov   esi, ebx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+
+    AS2(    mov   edi, ecx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, dh                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, al                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm1, esi                                              )
+
+
+             /* Put2 (mm2) =  
+                Te0[get2,rs 24] ^
+                Te1[get3,rs 16] ^
+                Te2[get0,rs  8] ^
+                Te3[get1,rs  0] 
+            */
+
+    AS2(    mov   esi, ecx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+
+    AS2(    mov   edi, edx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, ah                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, bl                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm2, esi                                              )
+
+             /* Put3 (edx) =  
+                Te0[get3,rs 24] ^
+                Te1[get0,rs 16] ^
+                Te2[get1,rs  8] ^
+                Te3[get2,rs  0] 
+            */
+
+    AS2(    mov   esi, edx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   edx, DWORD PTR [ebp + esi*4]                          )
+
+    AS2(    mov   edi, eax                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   edx, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx esi, bh                                               )
+    AS2(    xor   edx, DWORD PTR [ebp + 2048 + esi*4]                   )
+
+    AS2(    movzx edi, cl                                               )
+    AS2(    xor   edx, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+            // xOr
+
+    AS2(    movd   esi, mm6                      )   //  rk
+
+    AS2(    movd   eax, mm0                                             )
+    AS2(    add    esi, 16                                              )
+    AS2(    movd   ebx, mm1                                             )
+    AS2(    movd   mm6, esi                      )   //  save back
+    AS2(    movd   ecx, mm2                                             )
+
+    AS2(    xor   eax, DWORD PTR [esi]                                  )
+    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
+    AS2(    movd  edi, mm5                                              )
+    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
+    AS2(    xor   edx, DWORD PTR [esi + 12]                             )
+
+    AS1(    dec   edi                                                   )
+    AS2(    movd  mm5, edi                                              )
+
+    AS1(    jnz   loop1                                                 )
+
+            // last round
+            /*
+            Put0 (mm0) =
+                (Te4[get0, rs24] & 0xff000000) ^  h = 4278190080
+                (Te4[get1, rs16] & 0x00ff0000) ^  h =   16711680
+                (Te4[get2, rs 8] & 0x0000ff00) ^  h =      65280
+                (Te4[get3, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, eax                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, ebx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, ch                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, dl                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm0, esi                                              )
+
+            /*
+            Put1 (mm1) =
+                (Te4[get1, rs24] & 0xff000000) ^  h = 4278190080
+                (Te4[get2, rs16] & 0x00ff0000) ^  h =   16711680
+                (Te4[get3, rs 8] & 0x0000ff00) ^  h =      65280
+                (Te4[get0, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, ebx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, ecx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, dh                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, al                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm1, esi                                              )
+
+            /*
+            Put2 (mm2) =
+                (Te4[get2, rs24] & 0xff000000) ^  h = 4278190080
+                (Te4[get3, rs16] & 0x00ff0000) ^  h =   16711680
+                (Te4[get0, rs 8] & 0x0000ff00) ^  h =      65280
+                (Te4[get1, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, ecx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, edx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, ah                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, bl                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm2, esi                                              )
+
+            /*
+            Put3 (edx) =
+                (Te4[get3, rs24] & 0xff000000) ^  h = 4278190080
+                (Te4[get0, rs16] & 0x00ff0000) ^  h =   16711680
+                (Te4[get1, rs 8] & 0x0000ff00) ^  h =      65280
+                (Te4[get2, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, edx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   edx, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   edx, 4278190080                                       )
+
+    AS2(    mov   edi, eax                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   esi, 16711680                                         )
+    AS2(    xor   edx, esi                                              )
+
+    AS2(    movzx esi, bh                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   edx, edi                                              )
+
+    AS2(    movzx edi, cl                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   esi, 255                                              )
+    AS2(    xor   edx, esi                                              )
+
+    
+            // xOr
+    AS2(    movd   eax, mm0                                             )
+    AS2(    movd   esi, mm6                      )   //  rk
+    AS2(    movd   ebx, mm1                                             )
+    AS2(    add    esi, 16                                               )
+    AS2(    movd   ecx, mm2                                             )
+
+    AS2(    xor   eax, DWORD PTR [esi]                                  )
+    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
+    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
+    AS2(    xor   edx, DWORD PTR [esi + 12]                             )
+
+    // end
+    AS2(    movd  ebp, mm7                                              )
+
+            // swap
+    AS1(    bswap eax                                                   )
+    AS1(    bswap ebx                                                   )
+
+            // store
+    #ifdef __GNUC__
+        AS2(    mov esi, DWORD PTR [ebp + 16]       )   //  outBlock
+    #else
+        AS2(    mov esi, DWORD PTR [ebp + 12]       )   //  outBlock
+    #endif
+
+    AS1(    bswap ecx                                                   )
+    AS1(    bswap edx                                                   )
+
+    AS2(    mov DWORD PTR [esi],      eax                               )
+    AS2(    mov DWORD PTR [esi +  4], ebx                               )
+    AS2(    mov DWORD PTR [esi +  8], ecx                               )
+    AS2(    mov DWORD PTR [esi + 12], edx                               )
+
+
+    EPILOG()
+}
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void AES::AsmDecrypt(const byte* inBlock, byte* outBlock, void* boxes) const
+{
+
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    mov   edx, DWORD PTR [ecx + 60]     )   // rounds
+        AS2(    lea   edi, [ecx + 64]               )   // rk 
+    #else
+        AS2(    mov   edx, DWORD PTR [ecx + 56]     )   // rounds
+        AS2(    lea   edi, [ecx + 60]               )   // rk 
+    #endif
+   
+    AS1(    dec   edx                           )
+    AS2(    movd  mm6, edi                      )   // save rk
+    AS2(    movd  mm5, edx                      )   // save rounds
+
+    AS2(    mov   eax, DWORD PTR [esi]                                  )
+    AS2(    mov   ebx, DWORD PTR [esi + 4]                              )
+    AS2(    mov   ecx, DWORD PTR [esi + 8]                              )
+    AS2(    mov   edx, DWORD PTR [esi + 12]                             )
+
+    AS1(    bswap eax                                                   )
+    AS1(    bswap ebx                                                   )
+    AS1(    bswap ecx                                                   )
+    AS1(    bswap edx                                                   )
+
+    AS2(    xor   eax, DWORD PTR [edi]               )   // s0
+    AS2(    xor   ebx, DWORD PTR [edi +  4]          )   // s1
+    AS2(    xor   ecx, DWORD PTR [edi +  8]          )   // s2
+    AS2(    xor   edx, DWORD PTR [edi + 12]          )   // s3
+
+
+    AS1(loop2:                                                          )
+       /*   Put0 (mm0) =
+            Td0[GETBYTE(get0, rs24)] ^
+            Td1[GETBYTE(get3, rs16)] ^
+            Td2[GETBYTE(get2, rs 8)] ^
+            Td3[GETBYTE(tet1,     )]  
+        */
+    AS2(    mov   esi, eax                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+                                                    
+    AS2(    mov   edi, edx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, ch                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, bl                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm0, esi                                              )
+
+      /*    Put1 (mm1) =
+            Td0[GETBYTE(get1, rs24)] ^
+            Td1[GETBYTE(get0, rs16)] ^
+            Td2[GETBYTE(get3, rs 8)] ^
+            Td3[GETBYTE(tet2,     )]  
+        */
+    AS2(    mov   esi, ebx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+                                                    
+    AS2(    mov   edi, eax                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, dh                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, cl                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm1, esi                                              )
+
+      /*    Put2 (mm2) =
+            Td0[GETBYTE(get2, rs24)] ^
+            Td1[GETBYTE(get1, rs16)] ^
+            Td2[GETBYTE(get0, rs 8)] ^
+            Td3[GETBYTE(tet3,     )]  
+      */
+    AS2(    mov   esi, ecx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
+                                                    
+    AS2(    mov   edi, ebx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx edi, ah                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )
+
+    AS2(    movzx edi, dl                                               )
+    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+    AS2(    movd  mm2, esi                                              )
+
+      /*    Put3 (edx) =
+            Td0[GETBYTE(get3, rs24)] ^
+            Td1[GETBYTE(get2, rs16)] ^
+            Td2[GETBYTE(get1, rs 8)] ^
+            Td3[GETBYTE(tet0,     )]  
+      */
+    AS2(    mov   esi, edx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   edx, DWORD PTR [ebp + esi*4]                          )
+                                                    
+    AS2(    mov   edi, ecx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   edx, DWORD PTR [ebp + 1024 + edi*4]                   )
+
+    AS2(    movzx esi, bh                                               )
+    AS2(    xor   edx, DWORD PTR [ebp + 2048 + esi*4]                   )
+
+    AS2(    movzx edi, al                                               )
+    AS2(    xor   edx, DWORD PTR [ebp + 3072 + edi*4]                   )
+
+
+            // xOr
+
+    AS2(    movd  esi, mm6                      )   //  rk
+    AS2(    add   esi, 16                                               )
+    AS2(    movd  mm6, esi                      )   //  save back
+
+    AS2(    movd  eax, mm0                                              )
+    AS2(    movd  ebx, mm1                                              )
+    AS2(    movd  ecx, mm2                                              )
+
+    AS2(    xor   eax, DWORD PTR [esi]                                  )
+    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
+    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
+    AS2(    xor   edx, DWORD PTR [esi + 12]                             )
+
+    AS2(    movd  edi, mm5                                              )
+    AS1(    dec   edi                                                   )
+    AS2(    movd  mm5, edi                                              )
+
+    AS1(    jnz   loop2                                                 )
+
+            // last round
+            /*
+            Put0 (mm0) =
+                (Td4[get0, rs24] & 0xff000000) ^  h = 4278190080
+                (Td4[get3, rs16] & 0x00ff0000) ^  h =   16711680
+                (Td4[get2, rs 8] & 0x0000ff00) ^  h =      65280
+                (Td4[get1, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, eax                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, edx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, ch                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, bl                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm0, esi                                              )
+
+            /*
+            Put1 (mm1) =
+                (Td4[get1, rs24] & 0xff000000) ^  h = 4278190080
+                (Td4[get0, rs16] & 0x00ff0000) ^  h =   16711680
+                (Td4[get3, rs 8] & 0x0000ff00) ^  h =      65280
+                (Td4[get2, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, ebx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, eax                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, dh                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, cl                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm1, esi                                              )
+
+            /*
+            Put2 (mm2) =
+                (Td4[get2, rs24] & 0xff000000) ^  h = 4278190080
+                (Td4[get1, rs16] & 0x00ff0000) ^  h =   16711680
+                (Td4[get0, rs 8] & 0x0000ff00) ^  h =      65280
+                (Td4[get3, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, ecx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   esi, 4278190080                                       )
+
+    AS2(    mov   edi, ebx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 16711680                                         )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, ah                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movzx edi, dl                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   edi, 255                                              )
+    AS2(    xor   esi, edi                                              )
+
+    AS2(    movd  mm2, esi                                              )
+
+            /*
+            Put3 (edx) =
+                (Td4[get3, rs24] & 0xff000000) ^  h = 4278190080
+                (Td4[get2, rs16] & 0x00ff0000) ^  h =   16711680
+                (Td4[get1, rs 8] & 0x0000ff00) ^  h =      65280
+                (Td4[get0, rs 0] & 0x000000ff)    h =        255
+            */
+    AS2(    mov   esi, edx                                              )
+    AS2(    shr   esi, 24                                               )
+    AS2(    mov   edx, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   edx, 4278190080                                       )
+
+    AS2(    mov   edi, ecx                                              )
+    AS2(    shr   edi, 16                                               )
+    AS2(    and   edi, 255                                              )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   esi, 16711680                                         )
+    AS2(    xor   edx, esi                                              )
+
+    AS2(    movzx esi, bh                                               )
+    AS2(    mov   edi, DWORD PTR [ebp + 4096 + esi*4]                   )
+    AS2(    and   edi, 65280                                            )
+    AS2(    xor   edx, edi                                              )
+
+    AS2(    movzx edi, al                                               )
+    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
+    AS2(    and   esi, 255                                              )
+    AS2(    xor   edx, esi                                              )
+
+
+            // xOr
+    AS2(    movd  esi, mm6                      )   //  rk
+    AS2(    add   esi, 16                                               )
+
+    AS2(    movd   eax, mm0                                             )
+    AS2(    movd   ebx, mm1                                             )
+    AS2(    movd   ecx, mm2                                             )
+
+    AS2(    xor   eax, DWORD PTR [esi]                                  )
+    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
+    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
+    AS2(    xor   edx, DWORD PTR [esi + 12]                             )
+
+    // end
+    AS2(    movd  ebp, mm7                                              )
+
+            // swap
+    AS1(    bswap eax                                                   )
+    AS1(    bswap ebx                                                   )
+    AS1(    bswap ecx                                                   )
+    AS1(    bswap edx                                                   )
+
+            // store
+    #ifdef __GNUC__
+        AS2(    mov esi, DWORD PTR [ebp + 16]       )   //  outBlock
+    #else
+        AS2(    mov esi, DWORD PTR [ebp + 12]       )   //  outBlock
+    #endif
+    AS2(    mov DWORD PTR [esi],      eax                               )
+    AS2(    mov DWORD PTR [esi +  4], ebx                               )
+    AS2(    mov DWORD PTR [esi +  8], ecx                               )
+    AS2(    mov DWORD PTR [esi + 12], edx                               )
+
+
+    EPILOG()
+}
+
+
+
+#endif // defined(DO_AES_ASM)
+
+
+
+const word32 AES::Te[5][256] = {
+{
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+},
+{
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+},
+{
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+},
+{
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+},
+{
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+}
+};
+
+
+const word32 AES::Td[5][256] = {
+{
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+},
+{
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+},
+{
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+},
+{
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+},
+{
+    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+}
+};
+
+
+const word32* AES::Te0 = AES::Te[0];
+const word32* AES::Te1 = AES::Te[1];
+const word32* AES::Te2 = AES::Te[2];
+const word32* AES::Te3 = AES::Te[3];
+const word32* AES::Te4 = AES::Te[4];
+
+const word32* AES::Td0 = AES::Td[0];
+const word32* AES::Td1 = AES::Td[1];
+const word32* AES::Td2 = AES::Td[2];
+const word32* AES::Td3 = AES::Td[3];
+const word32* AES::Td4 = AES::Td[4];
+
+
 
 } // namespace
 
diff --git a/extra/yassl/taocrypt/src/aestables.cpp b/extra/yassl/taocrypt/src/aestables.cpp
index 7ba25bc9ffb..af9924703ef 100644
--- a/extra/yassl/taocrypt/src/aestables.cpp
+++ b/extra/yassl/taocrypt/src/aestables.cpp
@@ -28,689 +28,6 @@
 namespace TaoCrypt {
 
 
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-const word32 AES::Te0[256] = {
-    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
-    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
-    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
-    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
-    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
-    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
-    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
-    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
-    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
-    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
-    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
-    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
-    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
-    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
-    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
-    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
-    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
-    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
-    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
-    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
-    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
-    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
-    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
-    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
-    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
-    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
-    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
-    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
-    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
-    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
-    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
-    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
-    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
-    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
-    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
-    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
-    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
-    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
-    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
-    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
-    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
-    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
-    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
-    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
-    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
-    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
-    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
-    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
-    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
-    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
-    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
-    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
-    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
-    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
-    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
-    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
-    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
-    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
-    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
-    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
-    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
-    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
-    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
-    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-const word32 AES::Te1[256] = {
-    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
-    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
-    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
-    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
-    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
-    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
-    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
-    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
-    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
-    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
-    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
-    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
-    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
-    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
-    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
-    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
-    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
-    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
-    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
-    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
-    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
-    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
-    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
-    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
-    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
-    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
-    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
-    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
-    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
-    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
-    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
-    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
-    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
-    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
-    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
-    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
-    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
-    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
-    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
-    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
-    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
-    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
-    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
-    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
-    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
-    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
-    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
-    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
-    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
-    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
-    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
-    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
-    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
-    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
-    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
-    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
-    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
-    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
-    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
-    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
-    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
-    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
-    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
-    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-const word32 AES::Te2[256] = {
-    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
-    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
-    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
-    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
-    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
-    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
-    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
-    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
-    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
-    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
-    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
-    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
-    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
-    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
-    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
-    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
-    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
-    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
-    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
-    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
-    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
-    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
-    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
-    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
-    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
-    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
-    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
-    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
-    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
-    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
-    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
-    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
-    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
-    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
-    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
-    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
-    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
-    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
-    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
-    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
-    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
-    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
-    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
-    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
-    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
-    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
-    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
-    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
-    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
-    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
-    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
-    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
-    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
-    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
-    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
-    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
-    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
-    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
-    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
-    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
-    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
-    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
-    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
-    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-
-const word32 AES::Te3[256] = {
-    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
-    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
-    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
-    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
-    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
-    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
-    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
-    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
-    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
-    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
-    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
-    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
-    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
-    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
-    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
-    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
-    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
-    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
-    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
-    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
-    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
-    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
-    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
-    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
-    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
-    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
-    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
-    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
-    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
-    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
-    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
-    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
-    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
-    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
-    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
-    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
-    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
-    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
-    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
-    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
-    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
-    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
-    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
-    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
-    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
-    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
-    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
-    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
-    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
-    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
-    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
-    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
-    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
-    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
-    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
-    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
-    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
-    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
-    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
-    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
-    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
-    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
-    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
-    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-
-const word32 AES::Te4[256] = {
-    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
-    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
-    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
-    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
-    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
-    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
-    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
-    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
-    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
-    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
-    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
-    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
-    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
-    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
-    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
-    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
-    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
-    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
-    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
-    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
-    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
-    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
-    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
-    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
-    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
-    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
-    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
-    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
-    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
-    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
-    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
-    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
-    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
-    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
-    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
-    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
-    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
-    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
-    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
-    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
-    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
-    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
-    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
-    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
-    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
-    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
-    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
-    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
-    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
-    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
-    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
-    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
-    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
-    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
-    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
-    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
-    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
-    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
-    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
-    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
-    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
-    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
-    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
-    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-
-const word32 AES::Td0[256] = {
-    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
-    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
-    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
-    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
-    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
-    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
-    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
-    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
-    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
-    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
-    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
-    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
-    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
-    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
-    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
-    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
-    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
-    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
-    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
-    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
-    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
-    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
-    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
-    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
-    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
-    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
-    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
-    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
-    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
-    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
-    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
-    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
-    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
-    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
-    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
-    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
-    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
-    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
-    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
-    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
-    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
-    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
-    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
-    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
-    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
-    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
-    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
-    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
-    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
-    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
-    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
-    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
-    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
-    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
-    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
-    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
-    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
-    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
-    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
-    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
-    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
-    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
-    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
-    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-
-const word32 AES::Td1[256] = {
-    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
-    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
-    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
-    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
-    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
-    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
-    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
-    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
-    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
-    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
-    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
-    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
-    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
-    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
-    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
-    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
-    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
-    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
-    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
-    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
-    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
-    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
-    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
-    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
-    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
-    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
-    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
-    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
-    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
-    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
-    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
-    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
-    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
-    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
-    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
-    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
-    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
-    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
-    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
-    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
-    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
-    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
-    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
-    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
-    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
-    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
-    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
-    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
-    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
-    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
-    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
-    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
-    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
-    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
-    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
-    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
-    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
-    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
-    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
-    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
-    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
-    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
-    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
-    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-
-const word32 AES::Td2[256] = {
-    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
-    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
-    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
-    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
-    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
-    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
-    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
-    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
-    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
-    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
-    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
-    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
-    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
-    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
-    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
-    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
-    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
-    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
-    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
-    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
-    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
-    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
-    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
-    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
-    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
-    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
-    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
-    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
-    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
-    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
-    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
-    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
-    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
-    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
-    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
-    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
-    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
-    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
-    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
-    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
-    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
-    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
-    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
-    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
-    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
-    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
-    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
-    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
-    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
-    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
-    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
-    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
-    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
-    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
-    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
-    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
-    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
-    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
-    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
-    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
-    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
-    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
-    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
-    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-
-const word32 AES::Td3[256] = {
-    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
-    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
-    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
-    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
-    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
-    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
-    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
-    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
-    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
-    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
-    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
-    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
-    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
-    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
-    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
-    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
-    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
-    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
-    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
-    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
-    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
-    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
-    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
-    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
-    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
-    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
-    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
-    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
-    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
-    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
-    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
-    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
-    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
-    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
-    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
-    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
-    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
-    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
-    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
-    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
-    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
-    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
-    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
-    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
-    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
-    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
-    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
-    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
-    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
-    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
-    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
-    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
-    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
-    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
-    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
-    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
-    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
-    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
-    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
-    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
-    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
-    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
-    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
-    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-
-const word32 AES::Td4[256] = {
-    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
-    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
-    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
-    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
-    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
-    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
-    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
-    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
-    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
-    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
-    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
-    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
-    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
-    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
-    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
-    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
-    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
-    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
-    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
-    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
-    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
-    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
-    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
-    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
-    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
-    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
-    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
-    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
-    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
-    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
-    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
-    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
-    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
-    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
-    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
-    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
-    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
-    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
-    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
-    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
-    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
-    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
-    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
-    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
-    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
-    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
-    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
-    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
-    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
-    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
-    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
-    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
-    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
-    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
-    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
-    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
-    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
-    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
-    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
-    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
-    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
-    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
-    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
-    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-
 const word32 AES::rcon_[] = {
     0x01000000, 0x02000000, 0x04000000, 0x08000000,
     0x10000000, 0x20000000, 0x40000000, 0x80000000,
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index 8f4ce051a43..9c485609dd0 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -20,6 +20,8 @@
  */
 
 /* based on Wei Dai's algebra.cpp from CryptoPP */
+#undef  NDEBUG
+#define DEBUG   // GCC 4.0 bug if NDEBUG and Optimize > 1
 
 #include "runtime.hpp"
 #include "algebra.hpp"
diff --git a/extra/yassl/taocrypt/src/arc4.cpp b/extra/yassl/taocrypt/src/arc4.cpp
index 1e521b48f0c..6d1c4d4e3a6 100644
--- a/extra/yassl/taocrypt/src/arc4.cpp
+++ b/extra/yassl/taocrypt/src/arc4.cpp
@@ -25,6 +25,11 @@
 #include "arc4.hpp"
 
 
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_ARC4_ASM
+#endif
+
+
 namespace TaoCrypt {
 
 void ARC4::SetKey(const byte* key, word32 length)
@@ -71,6 +76,8 @@ inline unsigned int MakeByte(word32& x, word32& y, byte* s)
 } // namespace
 
 
+#ifndef DO_ARC4_ASM
+
 void ARC4::Process(byte* out, const byte* in, word32 length)
 {
     if (length == 0) return;
@@ -89,5 +96,134 @@ void ARC4::Process(byte* out, const byte* in, word32 length)
     y_ = y;
 }
 
+#else  // DO_ARC4_ASM
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void ARC4::Process(byte* out, const byte* in, word32 length)
+{
+#ifdef __GNUC__
+    #define AS1(x)    asm(#x);
+    #define AS2(x, y) asm(#x ", " #y);
+
+    #define PROLOG()  \
+        asm(".intel_syntax noprefix"); \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   edi, DWORD PTR [ebp + 12]     )   \
+        AS2(    mov   esi, DWORD PTR [ebp + 16]     )   \
+        AS2(    mov   ebp, DWORD PTR [ebp + 20]     )
+
+    #define EPILOG()  \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS1(    emms                            )   \
+        asm(".att_syntax");
+#else
+    #define AS1(x)    __asm x
+    #define AS2(x, y) __asm x, y
+
+    #define PROLOG() \
+        AS1(    push  ebp                       )   \
+        AS2(    mov   ebp, esp                  )   \
+        AS2(    movd  mm3, edi                  )   \
+        AS2(    movd  mm4, ebx                  )   \
+        AS2(    movd  mm5, esi                  )   \
+        AS2(    movd  mm6, ebp                  )   \
+        AS2(    mov   edi, DWORD PTR [ebp +  8] )   \
+        AS2(    mov   esi, DWORD PTR [ebp + 12] )   \
+        AS2(    mov   ebp, DWORD PTR [ebp + 16] )
+
+    #define EPILOG() \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS1(    pop   ebp                       )   \
+        AS1(    emms                            )   \
+        AS1(    ret 12                          )
+        
+#endif
+
+    PROLOG()
+
+    AS2(    sub    esp, 4                   )   // make room 
+
+    AS2(    cmp    ebp, 0                   )
+    AS1(    jz     nothing                  )
+
+    AS2(    mov    [esp], ebp               )   // length
+
+    AS2(    movzx  edx, BYTE PTR [ecx + 1]  )   // y
+    AS2(    lea    ebp, [ecx + 2]           )   // state_
+    AS2(    movzx  ecx, BYTE PTR [ecx]      )   // x
+
+    // setup loop
+    // a = s[x];
+    AS2(    movzx  eax, BYTE PTR [ebp + ecx]    )
+
+
+AS1( begin:                             )
+
+    // y = (y+a) & 0xff;
+    AS2(    add    edx, eax                     )
+    AS2(    and    edx, 255                     )
+
+    // b = s[y];
+    AS2(    movzx  ebx, BYTE PTR [ebp + edx]    )
+
+    // s[x] = b;
+    AS2(    mov    [ebp + ecx], bl              )
+
+    // s[y] = a;
+    AS2(    mov    [ebp + edx], al              )
+
+    // x = (x+1) & 0xff;
+    AS1(    inc    ecx                          )
+    AS2(    and    ecx, 255                     )
+
+    //return s[(a+b) & 0xff];
+    AS2(    add    eax, ebx                     )
+    AS2(    and    eax, 255                     )
+    
+    AS2(    movzx  ebx, BYTE PTR [ebp + eax]    )
+
+    // a = s[x];   for next round
+    AS2(    movzx  eax, BYTE PTR [ebp + ecx]    )
+
+    // xOr w/ inByte
+    AS2(    xor    bl,  BYTE PTR [esi]          )
+    AS1(    inc    esi                          )
+
+    // write to outByte
+    AS2(    mov    [edi], bl                    )
+    AS1(    inc    edi                          )
+
+    AS1(    dec    DWORD PTR [esp]              )
+    AS1(    jnz    begin                        )
+
+
+    // write back to x_ and y_
+    AS2(    mov    [ebp - 2], cl            )
+    AS2(    mov    [ebp - 1], dl            )
+
+
+AS1( nothing:                           )
+
+
+    EPILOG()
+}
+
+#endif // DO_ARC4_ASM
+
 
 }  // namespace
diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp
index 8f8d2ba52da..3efc26ab168 100644
--- a/extra/yassl/taocrypt/src/asn.cpp
+++ b/extra/yassl/taocrypt/src/asn.cpp
@@ -186,7 +186,7 @@ PublicKey::PublicKey(const byte* k, word32 s) : key_(0), sz_(0)
 void PublicKey::SetSize(word32 s)
 {
     sz_ = s;
-    key_ = new (tc) byte[sz_];
+    key_ = NEW_TC byte[sz_];
 }
 
 
@@ -198,7 +198,7 @@ void PublicKey::SetKey(const byte* k)
 
 void PublicKey::AddToEnd(const byte* data, word32 len)
 {
-    mySTL::auto_ptr tmp(new (tc) byte[sz_ + len], tcArrayDelete);
+    mySTL::auto_ptr tmp(NEW_TC byte[sz_ + len], tcArrayDelete);
 
     memcpy(tmp.get(), key_, sz_);
     memcpy(tmp.get() + sz_, data, len);
@@ -217,7 +217,7 @@ Signer::Signer(const byte* k, word32 kSz, const char* n, const byte* h)
 {
     if (n) {
         int sz = strlen(n);
-        name_ = new (tc) char[sz + 1];
+        name_ = NEW_TC char[sz + 1];
         memcpy(name_, n, sz);
         name_[sz] = 0;
     }
@@ -421,12 +421,13 @@ void DH_Decoder::Decode(DH& key)
 }
 
 
-CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers)
+CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers,
+                         bool noVerify, CertType ct)
     : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0),
-      signature_(0), issuer_(0), subject_(0)
+      signature_(0), issuer_(0), subject_(0), verify_(!noVerify)
 { 
     if (decode)
-        Decode(signers); 
+        Decode(signers, ct); 
 }
 
 
@@ -455,7 +456,7 @@ void CertDecoder::ReadHeader()
 
 
 // Decode a x509v3 Certificate
-void CertDecoder::Decode(SignerList* signers)
+void CertDecoder::Decode(SignerList* signers, CertType ct)
 {
     if (source_.GetError().What()) return;
     DecodeToKey();
@@ -473,12 +474,16 @@ void CertDecoder::Decode(SignerList* signers)
         return;
     }
 
+    if (ct == CA) {
     if ( memcmp(issuerHash_, subjectHash_, SHA::DIGEST_SIZE) == 0 ) {
-        if (!ValidateSelfSignature())
+            if (!ValidateSelfSignature() && verify_)
             source_.SetError(SIG_CONFIRM_E);
     }
     else
-        if (!ValidateSignature(signers))
+            if (!ValidateSignature(signers) && verify_)
+                source_.SetError(SIG_OTHER_E);
+    }
+    else if (!ValidateSignature(signers) && verify_)
             source_.SetError(SIG_OTHER_E);
 }
 
@@ -631,7 +636,7 @@ word32 CertDecoder::GetSignature()
     }
     sigLength_--;
 
-    signature_ = new (tc) byte[sigLength_];
+    signature_ = NEW_TC byte[sigLength_];
     memcpy(signature_, source_.get_current(), sigLength_);
     source_.advance(sigLength_);
 
@@ -652,7 +657,7 @@ word32 CertDecoder::GetDigest()
 
     sigLength_ = GetLength(source_);
 
-    signature_ = new (tc) byte[sigLength_];
+    signature_ = NEW_TC byte[sigLength_];
     memcpy(signature_, source_.get_current(), sigLength_);
     source_.advance(sigLength_);
 
@@ -692,7 +697,7 @@ void CertDecoder::GetName(NameType nt)
 
             if (id == COMMON_NAME) {
                 char*& ptr = (nt == ISSUER) ? issuer_ : subject_;
-                ptr = new (tc) char[strLen + 1];
+                ptr = NEW_TC char[strLen + 1];
                 memcpy(ptr, source_.get_current(), strLen);
                 ptr[strLen] = 0;
             }
@@ -734,7 +739,7 @@ void CertDecoder::GetDate(DateType dt)
     memcpy(date, source_.get_current(), length);
     source_.advance(length);
 
-    if (!ValidateDate(date, b, dt))
+    if (!ValidateDate(date, b, dt) && verify_)
         if (dt == BEFORE)
             source_.SetError(BEFORE_DATE_E);
         else
@@ -802,22 +807,22 @@ bool CertDecoder::ValidateSignature(SignerList* signers)
 }
 
 
-// RSA confirm
+// confirm certificate signature
 bool CertDecoder::ConfirmSignature(Source& pub)
 {
     HashType ht;
     mySTL::auto_ptr hasher(tcDelete);
 
     if (signatureOID_ == MD5wRSA) {
-        hasher.reset(new (tc) MD5);
+        hasher.reset(NEW_TC MD5);
         ht = MD5h;
     }
     else if (signatureOID_ == MD2wRSA) {
-        hasher.reset(new (tc) MD2);
+        hasher.reset(NEW_TC MD2);
         ht = MD2h;
     }
     else if (signatureOID_ == SHAwRSA || signatureOID_ == SHAwDSA) {
-        hasher.reset(new (tc) SHA);
+        hasher.reset(NEW_TC SHA);
         ht = SHAh;
     }
     else {
diff --git a/extra/yassl/taocrypt/src/bftables.cpp b/extra/yassl/taocrypt/src/bftables.cpp
new file mode 100644
index 00000000000..e072b117f54
--- /dev/null
+++ b/extra/yassl/taocrypt/src/bftables.cpp
@@ -0,0 +1,306 @@
+/* bftables.cpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* based on Wei Dai's bfinit.cpp from CryptoPP */
+
+#include "runtime.hpp"
+#include "blowfish.hpp"
+
+
+namespace TaoCrypt {
+
+const word32 Blowfish::p_init_[Blowfish::ROUNDS+2] =
+{
+  608135816U, 2242054355U,  320440878U,   57701188U,
+ 2752067618U,  698298832U,  137296536U, 3964562569U,
+ 1160258022U,  953160567U, 3193202383U,  887688300U,
+ 3232508343U, 3380367581U, 1065670069U, 3041331479U,
+ 2450970073U, 2306472731U
+} ;
+
+
+const word32 Blowfish::s_init_[4*256] = {
+ 3509652390U, 2564797868U,  805139163U, 3491422135U,
+ 3101798381U, 1780907670U, 3128725573U, 4046225305U,
+  614570311U, 3012652279U,  134345442U, 2240740374U,
+ 1667834072U, 1901547113U, 2757295779U, 4103290238U,
+  227898511U, 1921955416U, 1904987480U, 2182433518U,
+ 2069144605U, 3260701109U, 2620446009U,  720527379U,
+ 3318853667U,  677414384U, 3393288472U, 3101374703U,
+ 2390351024U, 1614419982U, 1822297739U, 2954791486U,
+ 3608508353U, 3174124327U, 2024746970U, 1432378464U,
+ 3864339955U, 2857741204U, 1464375394U, 1676153920U,
+ 1439316330U,  715854006U, 3033291828U,  289532110U,
+ 2706671279U, 2087905683U, 3018724369U, 1668267050U,
+  732546397U, 1947742710U, 3462151702U, 2609353502U,
+ 2950085171U, 1814351708U, 2050118529U,  680887927U,
+  999245976U, 1800124847U, 3300911131U, 1713906067U,
+ 1641548236U, 4213287313U, 1216130144U, 1575780402U,
+ 4018429277U, 3917837745U, 3693486850U, 3949271944U,
+  596196993U, 3549867205U,  258830323U, 2213823033U,
+  772490370U, 2760122372U, 1774776394U, 2652871518U,
+  566650946U, 4142492826U, 1728879713U, 2882767088U,
+ 1783734482U, 3629395816U, 2517608232U, 2874225571U,
+ 1861159788U,  326777828U, 3124490320U, 2130389656U,
+ 2716951837U,  967770486U, 1724537150U, 2185432712U,
+ 2364442137U, 1164943284U, 2105845187U,  998989502U,
+ 3765401048U, 2244026483U, 1075463327U, 1455516326U,
+ 1322494562U,  910128902U,  469688178U, 1117454909U,
+  936433444U, 3490320968U, 3675253459U, 1240580251U,
+  122909385U, 2157517691U,  634681816U, 4142456567U,
+ 3825094682U, 3061402683U, 2540495037U,   79693498U,
+ 3249098678U, 1084186820U, 1583128258U,  426386531U,
+ 1761308591U, 1047286709U,  322548459U,  995290223U,
+ 1845252383U, 2603652396U, 3431023940U, 2942221577U,
+ 3202600964U, 3727903485U, 1712269319U,  422464435U,
+ 3234572375U, 1170764815U, 3523960633U, 3117677531U,
+ 1434042557U,  442511882U, 3600875718U, 1076654713U,
+ 1738483198U, 4213154764U, 2393238008U, 3677496056U,
+ 1014306527U, 4251020053U,  793779912U, 2902807211U,
+  842905082U, 4246964064U, 1395751752U, 1040244610U,
+ 2656851899U, 3396308128U,  445077038U, 3742853595U,
+ 3577915638U,  679411651U, 2892444358U, 2354009459U,
+ 1767581616U, 3150600392U, 3791627101U, 3102740896U,
+  284835224U, 4246832056U, 1258075500U,  768725851U,
+ 2589189241U, 3069724005U, 3532540348U, 1274779536U,
+ 3789419226U, 2764799539U, 1660621633U, 3471099624U,
+ 4011903706U,  913787905U, 3497959166U,  737222580U,
+ 2514213453U, 2928710040U, 3937242737U, 1804850592U,
+ 3499020752U, 2949064160U, 2386320175U, 2390070455U,
+ 2415321851U, 4061277028U, 2290661394U, 2416832540U,
+ 1336762016U, 1754252060U, 3520065937U, 3014181293U,
+  791618072U, 3188594551U, 3933548030U, 2332172193U,
+ 3852520463U, 3043980520U,  413987798U, 3465142937U,
+ 3030929376U, 4245938359U, 2093235073U, 3534596313U,
+  375366246U, 2157278981U, 2479649556U,  555357303U,
+ 3870105701U, 2008414854U, 3344188149U, 4221384143U,
+ 3956125452U, 2067696032U, 3594591187U, 2921233993U,
+	2428461U,  544322398U,  577241275U, 1471733935U,
+  610547355U, 4027169054U, 1432588573U, 1507829418U,
+ 2025931657U, 3646575487U,  545086370U,   48609733U,
+ 2200306550U, 1653985193U,  298326376U, 1316178497U,
+ 3007786442U, 2064951626U,  458293330U, 2589141269U,
+ 3591329599U, 3164325604U,  727753846U, 2179363840U,
+  146436021U, 1461446943U, 4069977195U,  705550613U,
+ 3059967265U, 3887724982U, 4281599278U, 3313849956U,
+ 1404054877U, 2845806497U,  146425753U, 1854211946U,
+
+ 1266315497U, 3048417604U, 3681880366U, 3289982499U,
+ 2909710000U, 1235738493U, 2632868024U, 2414719590U,
+ 3970600049U, 1771706367U, 1449415276U, 3266420449U,
+  422970021U, 1963543593U, 2690192192U, 3826793022U,
+ 1062508698U, 1531092325U, 1804592342U, 2583117782U,
+ 2714934279U, 4024971509U, 1294809318U, 4028980673U,
+ 1289560198U, 2221992742U, 1669523910U,   35572830U,
+  157838143U, 1052438473U, 1016535060U, 1802137761U,
+ 1753167236U, 1386275462U, 3080475397U, 2857371447U,
+ 1040679964U, 2145300060U, 2390574316U, 1461121720U,
+ 2956646967U, 4031777805U, 4028374788U,   33600511U,
+ 2920084762U, 1018524850U,  629373528U, 3691585981U,
+ 3515945977U, 2091462646U, 2486323059U,  586499841U,
+  988145025U,  935516892U, 3367335476U, 2599673255U,
+ 2839830854U,  265290510U, 3972581182U, 2759138881U,
+ 3795373465U, 1005194799U,  847297441U,  406762289U,
+ 1314163512U, 1332590856U, 1866599683U, 4127851711U,
+  750260880U,  613907577U, 1450815602U, 3165620655U,
+ 3734664991U, 3650291728U, 3012275730U, 3704569646U,
+ 1427272223U,  778793252U, 1343938022U, 2676280711U,
+ 2052605720U, 1946737175U, 3164576444U, 3914038668U,
+ 3967478842U, 3682934266U, 1661551462U, 3294938066U,
+ 4011595847U,  840292616U, 3712170807U,  616741398U,
+  312560963U,  711312465U, 1351876610U,  322626781U,
+ 1910503582U,  271666773U, 2175563734U, 1594956187U,
+   70604529U, 3617834859U, 1007753275U, 1495573769U,
+ 4069517037U, 2549218298U, 2663038764U,  504708206U,
+ 2263041392U, 3941167025U, 2249088522U, 1514023603U,
+ 1998579484U, 1312622330U,  694541497U, 2582060303U,
+ 2151582166U, 1382467621U,  776784248U, 2618340202U,
+ 3323268794U, 2497899128U, 2784771155U,  503983604U,
+ 4076293799U,  907881277U,  423175695U,  432175456U,
+ 1378068232U, 4145222326U, 3954048622U, 3938656102U,
+ 3820766613U, 2793130115U, 2977904593U,   26017576U,
+ 3274890735U, 3194772133U, 1700274565U, 1756076034U,
+ 4006520079U, 3677328699U,  720338349U, 1533947780U,
+  354530856U,  688349552U, 3973924725U, 1637815568U,
+  332179504U, 3949051286U,   53804574U, 2852348879U,
+ 3044236432U, 1282449977U, 3583942155U, 3416972820U,
+ 4006381244U, 1617046695U, 2628476075U, 3002303598U,
+ 1686838959U,  431878346U, 2686675385U, 1700445008U,
+ 1080580658U, 1009431731U,  832498133U, 3223435511U,
+ 2605976345U, 2271191193U, 2516031870U, 1648197032U,
+ 4164389018U, 2548247927U,  300782431U,  375919233U,
+  238389289U, 3353747414U, 2531188641U, 2019080857U,
+ 1475708069U,  455242339U, 2609103871U,  448939670U,
+ 3451063019U, 1395535956U, 2413381860U, 1841049896U,
+ 1491858159U,  885456874U, 4264095073U, 4001119347U,
+ 1565136089U, 3898914787U, 1108368660U,  540939232U,
+ 1173283510U, 2745871338U, 3681308437U, 4207628240U,
+ 3343053890U, 4016749493U, 1699691293U, 1103962373U,
+ 3625875870U, 2256883143U, 3830138730U, 1031889488U,
+ 3479347698U, 1535977030U, 4236805024U, 3251091107U,
+ 2132092099U, 1774941330U, 1199868427U, 1452454533U,
+  157007616U, 2904115357U,  342012276U,  595725824U,
+ 1480756522U,  206960106U,  497939518U,  591360097U,
+  863170706U, 2375253569U, 3596610801U, 1814182875U,
+ 2094937945U, 3421402208U, 1082520231U, 3463918190U,
+ 2785509508U,  435703966U, 3908032597U, 1641649973U,
+ 2842273706U, 3305899714U, 1510255612U, 2148256476U,
+ 2655287854U, 3276092548U, 4258621189U,  236887753U,
+ 3681803219U,  274041037U, 1734335097U, 3815195456U,
+ 3317970021U, 1899903192U, 1026095262U, 4050517792U,
+  356393447U, 2410691914U, 3873677099U, 3682840055U,
+
+ 3913112168U, 2491498743U, 4132185628U, 2489919796U,
+ 1091903735U, 1979897079U, 3170134830U, 3567386728U,
+ 3557303409U,  857797738U, 1136121015U, 1342202287U,
+  507115054U, 2535736646U,  337727348U, 3213592640U,
+ 1301675037U, 2528481711U, 1895095763U, 1721773893U,
+ 3216771564U,   62756741U, 2142006736U,  835421444U,
+ 2531993523U, 1442658625U, 3659876326U, 2882144922U,
+  676362277U, 1392781812U,  170690266U, 3921047035U,
+ 1759253602U, 3611846912U, 1745797284U,  664899054U,
+ 1329594018U, 3901205900U, 3045908486U, 2062866102U,
+ 2865634940U, 3543621612U, 3464012697U, 1080764994U,
+  553557557U, 3656615353U, 3996768171U,  991055499U,
+  499776247U, 1265440854U,  648242737U, 3940784050U,
+  980351604U, 3713745714U, 1749149687U, 3396870395U,
+ 4211799374U, 3640570775U, 1161844396U, 3125318951U,
+ 1431517754U,  545492359U, 4268468663U, 3499529547U,
+ 1437099964U, 2702547544U, 3433638243U, 2581715763U,
+ 2787789398U, 1060185593U, 1593081372U, 2418618748U,
+ 4260947970U,   69676912U, 2159744348U,   86519011U,
+ 2512459080U, 3838209314U, 1220612927U, 3339683548U,
+  133810670U, 1090789135U, 1078426020U, 1569222167U,
+  845107691U, 3583754449U, 4072456591U, 1091646820U,
+  628848692U, 1613405280U, 3757631651U,  526609435U,
+  236106946U,   48312990U, 2942717905U, 3402727701U,
+ 1797494240U,  859738849U,  992217954U, 4005476642U,
+ 2243076622U, 3870952857U, 3732016268U,  765654824U,
+ 3490871365U, 2511836413U, 1685915746U, 3888969200U,
+ 1414112111U, 2273134842U, 3281911079U, 4080962846U,
+  172450625U, 2569994100U,  980381355U, 4109958455U,
+ 2819808352U, 2716589560U, 2568741196U, 3681446669U,
+ 3329971472U, 1835478071U,  660984891U, 3704678404U,
+ 4045999559U, 3422617507U, 3040415634U, 1762651403U,
+ 1719377915U, 3470491036U, 2693910283U, 3642056355U,
+ 3138596744U, 1364962596U, 2073328063U, 1983633131U,
+  926494387U, 3423689081U, 2150032023U, 4096667949U,
+ 1749200295U, 3328846651U,  309677260U, 2016342300U,
+ 1779581495U, 3079819751U,  111262694U, 1274766160U,
+  443224088U,  298511866U, 1025883608U, 3806446537U,
+ 1145181785U,  168956806U, 3641502830U, 3584813610U,
+ 1689216846U, 3666258015U, 3200248200U, 1692713982U,
+ 2646376535U, 4042768518U, 1618508792U, 1610833997U,
+ 3523052358U, 4130873264U, 2001055236U, 3610705100U,
+ 2202168115U, 4028541809U, 2961195399U, 1006657119U,
+ 2006996926U, 3186142756U, 1430667929U, 3210227297U,
+ 1314452623U, 4074634658U, 4101304120U, 2273951170U,
+ 1399257539U, 3367210612U, 3027628629U, 1190975929U,
+ 2062231137U, 2333990788U, 2221543033U, 2438960610U,
+ 1181637006U,  548689776U, 2362791313U, 3372408396U,
+ 3104550113U, 3145860560U,  296247880U, 1970579870U,
+ 3078560182U, 3769228297U, 1714227617U, 3291629107U,
+ 3898220290U,  166772364U, 1251581989U,  493813264U,
+  448347421U,  195405023U, 2709975567U,  677966185U,
+ 3703036547U, 1463355134U, 2715995803U, 1338867538U,
+ 1343315457U, 2802222074U, 2684532164U,  233230375U,
+ 2599980071U, 2000651841U, 3277868038U, 1638401717U,
+ 4028070440U, 3237316320U,    6314154U,  819756386U,
+  300326615U,  590932579U, 1405279636U, 3267499572U,
+ 3150704214U, 2428286686U, 3959192993U, 3461946742U,
+ 1862657033U, 1266418056U,  963775037U, 2089974820U,
+ 2263052895U, 1917689273U,  448879540U, 3550394620U,
+ 3981727096U,  150775221U, 3627908307U, 1303187396U,
+  508620638U, 2975983352U, 2726630617U, 1817252668U,
+ 1876281319U, 1457606340U,  908771278U, 3720792119U,
+ 3617206836U, 2455994898U, 1729034894U, 1080033504U,
+
+  976866871U, 3556439503U, 2881648439U, 1522871579U,
+ 1555064734U, 1336096578U, 3548522304U, 2579274686U,
+ 3574697629U, 3205460757U, 3593280638U, 3338716283U,
+ 3079412587U,  564236357U, 2993598910U, 1781952180U,
+ 1464380207U, 3163844217U, 3332601554U, 1699332808U,
+ 1393555694U, 1183702653U, 3581086237U, 1288719814U,
+  691649499U, 2847557200U, 2895455976U, 3193889540U,
+ 2717570544U, 1781354906U, 1676643554U, 2592534050U,
+ 3230253752U, 1126444790U, 2770207658U, 2633158820U,
+ 2210423226U, 2615765581U, 2414155088U, 3127139286U,
+  673620729U, 2805611233U, 1269405062U, 4015350505U,
+ 3341807571U, 4149409754U, 1057255273U, 2012875353U,
+ 2162469141U, 2276492801U, 2601117357U,  993977747U,
+ 3918593370U, 2654263191U,  753973209U,   36408145U,
+ 2530585658U,   25011837U, 3520020182U, 2088578344U,
+  530523599U, 2918365339U, 1524020338U, 1518925132U,
+ 3760827505U, 3759777254U, 1202760957U, 3985898139U,
+ 3906192525U,  674977740U, 4174734889U, 2031300136U,
+ 2019492241U, 3983892565U, 4153806404U, 3822280332U,
+  352677332U, 2297720250U,   60907813U,   90501309U,
+ 3286998549U, 1016092578U, 2535922412U, 2839152426U,
+  457141659U,  509813237U, 4120667899U,  652014361U,
+ 1966332200U, 2975202805U,   55981186U, 2327461051U,
+  676427537U, 3255491064U, 2882294119U, 3433927263U,
+ 1307055953U,  942726286U,  933058658U, 2468411793U,
+ 3933900994U, 4215176142U, 1361170020U, 2001714738U,
+ 2830558078U, 3274259782U, 1222529897U, 1679025792U,
+ 2729314320U, 3714953764U, 1770335741U,  151462246U,
+ 3013232138U, 1682292957U, 1483529935U,  471910574U,
+ 1539241949U,  458788160U, 3436315007U, 1807016891U,
+ 3718408830U,  978976581U, 1043663428U, 3165965781U,
+ 1927990952U, 4200891579U, 2372276910U, 3208408903U,
+ 3533431907U, 1412390302U, 2931980059U, 4132332400U,
+ 1947078029U, 3881505623U, 4168226417U, 2941484381U,
+ 1077988104U, 1320477388U,  886195818U,   18198404U,
+ 3786409000U, 2509781533U,  112762804U, 3463356488U,
+ 1866414978U,  891333506U,   18488651U,  661792760U,
+ 1628790961U, 3885187036U, 3141171499U,  876946877U,
+ 2693282273U, 1372485963U,  791857591U, 2686433993U,
+ 3759982718U, 3167212022U, 3472953795U, 2716379847U,
+  445679433U, 3561995674U, 3504004811U, 3574258232U,
+   54117162U, 3331405415U, 2381918588U, 3769707343U,
+ 4154350007U, 1140177722U, 4074052095U,  668550556U,
+ 3214352940U,  367459370U,  261225585U, 2610173221U,
+ 4209349473U, 3468074219U, 3265815641U,  314222801U,
+ 3066103646U, 3808782860U,  282218597U, 3406013506U,
+ 3773591054U,  379116347U, 1285071038U,  846784868U,
+ 2669647154U, 3771962079U, 3550491691U, 2305946142U,
+  453669953U, 1268987020U, 3317592352U, 3279303384U,
+ 3744833421U, 2610507566U, 3859509063U,  266596637U,
+ 3847019092U,  517658769U, 3462560207U, 3443424879U,
+  370717030U, 4247526661U, 2224018117U, 4143653529U,
+ 4112773975U, 2788324899U, 2477274417U, 1456262402U,
+ 2901442914U, 1517677493U, 1846949527U, 2295493580U,
+ 3734397586U, 2176403920U, 1280348187U, 1908823572U,
+ 3871786941U,  846861322U, 1172426758U, 3287448474U,
+ 3383383037U, 1655181056U, 3139813346U,  901632758U,
+ 1897031941U, 2986607138U, 3066810236U, 3447102507U,
+ 1393639104U,  373351379U,  950779232U,  625454576U,
+ 3124240540U, 4148612726U, 2007998917U,  544563296U,
+ 2244738638U, 2330496472U, 2058025392U, 1291430526U,
+  424198748U,   50039436U,   29584100U, 3605783033U,
+ 2429876329U, 2791104160U, 1057563949U, 3255363231U,
+ 3075367218U, 3463963227U, 1469046755U,  985887462U
+};
+
+
+
+
+} // namespace
+
diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp
new file mode 100644
index 00000000000..16e2277dc10
--- /dev/null
+++ b/extra/yassl/taocrypt/src/blowfish.cpp
@@ -0,0 +1,358 @@
+/* blowfish.cpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* C++ code based on Wei Dai's blowfish.cpp from CryptoPP */
+/* x86 asm is original */
+
+
+#if defined(TAOCRYPT_KERNEL_MODE)
+    #define DO_TAOCRYPT_KERNEL_MODE
+#endif                                  // only some modules now support this
+
+
+#include "runtime.hpp"
+#include "blowfish.hpp"
+
+
+
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_BLOWFISH_ASM
+#endif
+
+
+
+namespace TaoCrypt {
+
+
+#if !defined(DO_BLOWFISH_ASM)
+
+// Generic Version
+void Blowfish::Process(byte* out, const byte* in, word32 sz)
+{
+    if (mode_ == ECB)
+        ECB_Process(out, in, sz);
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            CBC_Encrypt(out, in, sz);
+        else
+            CBC_Decrypt(out, in, sz);
+}
+
+#else
+
+// ia32 optimized version
+void Blowfish::Process(byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / BLOCK_SIZE;
+
+    if (mode_ == ECB)
+        while (blocks--) {
+            AsmProcess(in, out);
+            out += BLOCK_SIZE;
+            in  += BLOCK_SIZE;
+        }
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            while (blocks--) {
+                r_[0] ^= *(word32*)in;
+                r_[1] ^= *(word32*)(in + 4);
+
+                AsmProcess((byte*)r_, (byte*)r_);
+                
+                memcpy(out, r_, BLOCK_SIZE);
+
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+        else
+            while (blocks--) {
+                AsmProcess(in, out);
+                
+                *(word32*)out       ^= r_[0];
+                *(word32*)(out + 4) ^= r_[1];
+
+                memcpy(r_, in, BLOCK_SIZE);
+
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+}
+
+#endif // DO_BLOWFISH_ASM
+
+
+void Blowfish::SetKey(const byte* key_string, word32 keylength, CipherDir dir)
+{
+	assert(keylength >= 4 && keylength <= 56);
+
+	unsigned i, j=0, k;
+	word32 data, dspace[2] = {0, 0};
+
+	memcpy(pbox_, p_init_, sizeof(p_init_));
+	memcpy(sbox_, s_init_, sizeof(s_init_));
+
+	// Xor key string into encryption key vector
+	for (i=0 ; i> 8)&0xFF)
+#define BFBYTE_2(x) ((x>>16)&0xFF)
+#define BFBYTE_3(x) ( x>>24)
+
+
+#define BF_S(Put, Get, I) (\
+        Put ^= p[I], \
+		tmp =  p[18 + BFBYTE_3(Get)],  \
+        tmp += p[274+ BFBYTE_2(Get)],  \
+        tmp ^= p[530+ BFBYTE_1(Get)],  \
+        tmp += p[786+ BFBYTE_0(Get)],  \
+        Put ^= tmp \
+    )
+
+
+#define BF_ROUNDS           \
+    BF_S(right, left,  1);  \
+    BF_S(left,  right, 2);  \
+    BF_S(right, left,  3);  \
+    BF_S(left,  right, 4);  \
+    BF_S(right, left,  5);  \
+    BF_S(left,  right, 6);  \
+    BF_S(right, left,  7);  \
+    BF_S(left,  right, 8);  \
+    BF_S(right, left,  9);  \
+    BF_S(left,  right, 10); \
+    BF_S(right, left,  11); \
+    BF_S(left,  right, 12); \
+    BF_S(right, left,  13); \
+    BF_S(left,  right, 14); \
+    BF_S(right, left,  15); \
+    BF_S(left,  right, 16); 
+
+#define BF_EXTRA_ROUNDS     \
+    BF_S(right, left,  17); \
+    BF_S(left,  right, 18); \
+    BF_S(right, left,  19); \
+    BF_S(left,  right, 20);
+
+
+// Used by key setup, no byte swapping
+void Blowfish::crypt_block(const word32 in[2], word32 out[2]) const
+{
+	word32 left  = in[0];
+	word32 right = in[1];
+
+	const word32* p = pbox_;
+    word32 tmp;
+
+	left ^= p[0];
+
+    BF_ROUNDS
+
+#if ROUNDS == 20
+    BF_EXTRA_ROUNDS
+#endif
+
+	right ^= p[ROUNDS + 1];
+
+	out[0] = right;
+	out[1] = left;
+}
+
+
+typedef BlockGetAndPut gpBlock;
+
+void Blowfish::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out)
+    const
+{
+    word32 tmp, left, right;
+    const word32* p = pbox_;
+    
+    gpBlock::Get(in)(left)(right);
+	left ^= p[0];
+
+    BF_ROUNDS
+
+#if ROUNDS == 20
+    BF_EXTRA_ROUNDS
+#endif
+
+	right ^= p[ROUNDS + 1];
+
+    gpBlock::Put(xOr, out)(right)(left);
+}
+
+
+#if defined(DO_BLOWFISH_ASM)
+    #ifdef __GNUC__
+        #define AS1(x)    asm(#x);
+        #define AS2(x, y) asm(#x ", " #y);
+
+        #define PROLOG()  \
+            asm(".intel_syntax noprefix"); \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    movd  mm5, esi                      )   \
+            AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+            AS2(    mov   esi, DWORD PTR [ebp + 12]     )
+
+        #define EPILOG()  \
+            AS2(    movd esi, mm5                  )   \
+            AS2(    movd ebx, mm4                  )   \
+            AS2(    movd edi, mm3                  )   \
+            AS1(    emms                           )   \
+            asm(".att_syntax");
+    #else
+        #define AS1(x)    __asm x
+        #define AS2(x, y) __asm x, y
+
+        #define PROLOG() \
+            AS1(    push  ebp                           )   \
+            AS2(    mov   ebp, esp                      )   \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    movd  mm5, esi                      )   \
+            AS2(    mov   esi, DWORD PTR [ebp +  8]     )
+
+        #define EPILOG()  \
+            AS2(    movd esi, mm5                       )   \
+            AS2(    movd ebx, mm4                       )   \
+            AS2(    movd edi, mm3                       )   \
+            AS2(    mov  esp, ebp                       )   \
+            AS1(    pop  ebp                            )   \
+            AS1(    emms                                )   \
+            AS1(    ret 8                               )
+            
+    #endif
+
+
+#define BF_ROUND(P, G, I)   \
+    /* Put ^= p[I]  */                              \
+    AS2(    xor   P,   [edi + I*4]              )   \
+    /* tmp =  p[18 + BFBYTE_3(Get)] */              \
+    AS2(    mov   ecx, G                        )   \
+    AS2(    shr   ecx, 16                       )   \
+    AS2(    movzx edx, ch                       )   \
+    AS2(    mov   esi, [edi + edx*4 +   72]     )   \
+    /* tmp += p[274+ BFBYTE_2(Get)] */              \
+    AS2(    movzx ecx, cl                       )   \
+    AS2(    add   esi, [edi + ecx*4 + 1096]     )   \
+    /* tmp ^= p[530+ BFBYTE_1(Get)] */              \
+    AS2(    mov   ecx, G                        )   \
+    AS2(    movzx edx, ch                       )   \
+    AS2(    xor   esi, [edi + edx*4 + 2120]     )   \
+    /* tmp += p[786+ BFBYTE_0(Get)] */              \
+    AS2(    movzx ecx, cl                       )   \
+    AS2(    add   esi, [edi + ecx*4 + 3144]     )   \
+    /* Put ^= tmp */                                \
+    AS2(    xor   P,   esi                      )
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void Blowfish::AsmProcess(const byte* inBlock, byte* outBlock) const
+{
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    lea   edi, [ecx + 60]                       )   // pbox
+    #else
+        AS2(    lea   edi, [ecx + 56]                       )   // pbox
+    #endif
+
+    AS2(    mov   eax, DWORD PTR [esi]                                  )
+    AS2(    mov   edx, DWORD PTR [edi]                                  )
+    AS1(    bswap eax                                                   )
+
+    AS2(    mov   ebx, DWORD PTR [esi + 4]                              )
+    AS2(    xor   eax, edx                      )   // left
+    AS1(    bswap ebx                           )   // right
+
+
+    BF_ROUND(ebx, eax, 1)
+    BF_ROUND(eax, ebx, 2)
+    BF_ROUND(ebx, eax, 3)
+    BF_ROUND(eax, ebx, 4)
+    BF_ROUND(ebx, eax, 5)
+    BF_ROUND(eax, ebx, 6)
+    BF_ROUND(ebx, eax, 7)
+    BF_ROUND(eax, ebx, 8)
+    BF_ROUND(ebx, eax, 9)
+    BF_ROUND(eax, ebx, 10)
+    BF_ROUND(ebx, eax, 11)
+    BF_ROUND(eax, ebx, 12)
+    BF_ROUND(ebx, eax, 13)
+    BF_ROUND(eax, ebx, 14)
+    BF_ROUND(ebx, eax, 15)
+    BF_ROUND(eax, ebx, 16)
+    #if ROUNDS == 20
+        BF_ROUND(ebx, eax, 17)
+        BF_ROUND(eax, ebx, 18)
+        BF_ROUND(ebx, eax, 19)
+        BF_ROUND(eax, ebx, 20)
+
+        AS2(    xor   ebx, [edi + 84]           )   // 20 + 1 (x4)
+    #else
+        AS2(    xor   ebx, [edi + 68]           )   // 16 + 1 (x4)
+    #endif
+
+    #ifdef __GNUC__
+        AS2(    mov   edi, [ebp + 16]           ) // outBlock
+    #else
+        AS2(    mov   edi, [ebp + 12]           ) // outBlock
+    #endif
+
+    AS1(    bswap ebx                           )
+    AS1(    bswap eax                           )
+
+    AS2(    mov   [edi]    , ebx                )
+    AS2(    mov   [edi + 4], eax                )
+
+    EPILOG()
+}
+
+
+#endif  // DO_BLOWFISH_ASM
+
+
+} // namespace
+
diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp
index 944a47c288e..01ea399df13 100644
--- a/extra/yassl/taocrypt/src/coding.cpp
+++ b/extra/yassl/taocrypt/src/coding.cpp
@@ -130,7 +130,7 @@ void Base64Encoder::Encode()
     word32 outSz = bytes * 4 / 3;
     outSz += (outSz % 4);           // 4 byte integrals         
 
-    outSz += outSz / pemLineSz + ( (outSz % pemLineSz) ? 1 : 0);  // new lines
+    outSz += (outSz + pemLineSz - 1) / pemLineSz;  // new lines
     encoded_.New(outSz);
 
     word32 i = 0;
@@ -187,9 +187,8 @@ void Base64Encoder::Encode()
 void Base64Decoder::Decode()
 {
     word32 bytes = coded_.size();
-    word32 plainSz = bytes - (bytes / pemLineSz + ( (bytes % pemLineSz) ? 
-                                                                      1 : 0));
-    plainSz = plainSz * 3 / 4 + (( (plainSz * 3) % 4) ? 1 : 0);
+    word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz); 
+    plainSz = (plainSz * 3 + 3) / 4;
     decoded_.New(plainSz);
 
     word32 i = 0;
diff --git a/extra/yassl/taocrypt/src/des.cpp b/extra/yassl/taocrypt/src/des.cpp
index e5d3331500c..d2db4fc939e 100644
--- a/extra/yassl/taocrypt/src/des.cpp
+++ b/extra/yassl/taocrypt/src/des.cpp
@@ -19,14 +19,25 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-/* based on Wei Dai's des.cpp from CryptoPP */
+/* C++ part based on Wei Dai's des.cpp from CryptoPP */
+/* x86 asm is original */
+
+
+#if defined(TAOCRYPT_KERNEL_MODE)
+    #define DO_TAOCRYPT_KERNEL_MODE
+#endif                                  // only some modules now support this
+
 
 #include "runtime.hpp"
 #include "des.hpp"
-#include 
 #include "algorithm.hpp"    // mySTL::swap
 
 
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_DES_ASM
+#endif
+
+
 namespace TaoCrypt {
 
 
@@ -67,101 +78,7 @@ static const int bytebit[] = {
        0200,0100,040,020,010,04,02,01
 };
 
-
-void DES::SetKey(const byte* key, word32 /*length*/, CipherDir dir)
-{
-    byte buffer[56+56+8];
-    byte *const pc1m = buffer;                 /* place to modify pc1 into */
-    byte *const pcr = pc1m + 56;               /* place to rotate pc1 into */
-    byte *const ks = pcr + 56;
-    register int i,j,l;
-    int m;
-
-    for (j = 0; j < 56; j++) {          /* convert pc1 to bits of key */
-        l = pc1[j] - 1;                 /* integer bit location  */
-        m = l & 07;                     /* find bit              */
-        pc1m[j] = (key[l >> 3] &        /* find which key byte l is in */
-            bytebit[m])                 /* and which bit of that byte */
-            ? 1 : 0;                    /* and store 1-bit result */
-    }
-    for (i = 0; i < 16; i++) {          /* key chunk for each iteration */
-        memset(ks, 0, 8);               /* Clear key schedule */
-        for (j = 0; j < 56; j++)        /* rotate pc1 the right amount */
-            pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
-        /* rotate left and right halves independently */
-        for (j = 0; j < 48; j++){   /* select bits individually */
-            /* check bit that goes to ks[j] */
-            if (pcr[pc2[j] - 1]){
-                /* mask it in if it's there */
-                l= j % 6;
-                ks[j/6] |= bytebit[l] >> 2;
-            }
-        }
-        /* Now convert to odd/even interleaved form for use in F */
-        k_[2*i] = ((word32)ks[0] << 24)
-            | ((word32)ks[2] << 16)
-            | ((word32)ks[4] << 8)
-            | ((word32)ks[6]);
-        k_[2*i + 1] = ((word32)ks[1] << 24)
-            | ((word32)ks[3] << 16)
-            | ((word32)ks[5] << 8)
-            | ((word32)ks[7]);
-    }
-    
-    // reverse key schedule order
-    if (dir == DECRYPTION)
-        for (i = 0; i < 16; i += 2) {
-            mySTL::swap(k_[i],   k_[32 - 2 - i]);
-            mySTL::swap(k_[i+1], k_[32 - 1 - i]);
-        }
-   
-}
-
-static inline void IPERM(word32& left, word32& right)
-{
-    word32 work;
-
-    right = rotlFixed(right, 4U);
-    work = (left ^ right) & 0xf0f0f0f0;
-    left ^= work;
-    right = rotrFixed(right^work, 20U);
-    work = (left ^ right) & 0xffff0000;
-    left ^= work;
-    right = rotrFixed(right^work, 18U);
-    work = (left ^ right) & 0x33333333;
-    left ^= work;
-    right = rotrFixed(right^work, 6U);
-    work = (left ^ right) & 0x00ff00ff;
-    left ^= work;
-    right = rotlFixed(right^work, 9U);
-    work = (left ^ right) & 0xaaaaaaaa;
-    left = rotlFixed(left^work, 1U);
-    right ^= work;
-}
-
-static inline void FPERM(word32& left, word32& right)
-{
-    word32 work;
-
-    right = rotrFixed(right, 1U);
-    work = (left ^ right) & 0xaaaaaaaa;
-    right ^= work;
-    left = rotrFixed(left^work, 9U);
-    work = (left ^ right) & 0x00ff00ff;
-    right ^= work;
-    left = rotlFixed(left^work, 6U);
-    work = (left ^ right) & 0x33333333;
-    right ^= work;
-    left = rotlFixed(left^work, 18U);
-    work = (left ^ right) & 0xffff0000;
-    right ^= work;
-    left = rotlFixed(left^work, 20U);
-    work = (left ^ right) & 0xf0f0f0f0;
-    right ^= work;
-    left = rotrFixed(left^work, 4U);
-}
-
-const word32 Spbox[DES::BOXES][DES::BOX_SIZE] = {
+const word32 Spbox[8][64] = {
 {
 0x01010400,0x00000000,0x00010000,0x01010404,
 0x01010004,0x00010404,0x00000004,0x00010000,
@@ -301,8 +218,105 @@ const word32 Spbox[DES::BOXES][DES::BOX_SIZE] = {
 };
 
 
+void BasicDES::SetKey(const byte* key, word32 /*length*/, CipherDir dir)
+{
+    byte buffer[56+56+8];
+    byte *const pc1m = buffer;                 /* place to modify pc1 into */
+    byte *const pcr = pc1m + 56;               /* place to rotate pc1 into */
+    byte *const ks = pcr + 56;
+    register int i,j,l;
+    int m;
 
-void DES::RawProcessBlock(word32& lIn, word32& rIn) const
+    for (j = 0; j < 56; j++) {          /* convert pc1 to bits of key */
+        l = pc1[j] - 1;                 /* integer bit location  */
+        m = l & 07;                     /* find bit              */
+        pc1m[j] = (key[l >> 3] &        /* find which key byte l is in */
+            bytebit[m])                 /* and which bit of that byte */
+            ? 1 : 0;                    /* and store 1-bit result */
+    }
+    for (i = 0; i < 16; i++) {          /* key chunk for each iteration */
+        memset(ks, 0, 8);               /* Clear key schedule */
+        for (j = 0; j < 56; j++)        /* rotate pc1 the right amount */
+            pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
+        /* rotate left and right halves independently */
+        for (j = 0; j < 48; j++){   /* select bits individually */
+            /* check bit that goes to ks[j] */
+            if (pcr[pc2[j] - 1]){
+                /* mask it in if it's there */
+                l= j % 6;
+                ks[j/6] |= bytebit[l] >> 2;
+            }
+        }
+        /* Now convert to odd/even interleaved form for use in F */
+        k_[2*i] = ((word32)ks[0] << 24)
+            | ((word32)ks[2] << 16)
+            | ((word32)ks[4] << 8)
+            | ((word32)ks[6]);
+        k_[2*i + 1] = ((word32)ks[1] << 24)
+            | ((word32)ks[3] << 16)
+            | ((word32)ks[5] << 8)
+            | ((word32)ks[7]);
+    }
+    
+    // reverse key schedule order
+    if (dir == DECRYPTION)
+        for (i = 0; i < 16; i += 2) {
+            mySTL::swap(k_[i],   k_[32 - 2 - i]);
+            mySTL::swap(k_[i+1], k_[32 - 1 - i]);
+        }
+   
+}
+
+static inline void IPERM(word32& left, word32& right)
+{
+    word32 work;
+
+    right = rotlFixed(right, 4U);
+    work = (left ^ right) & 0xf0f0f0f0;
+    left ^= work;
+
+    right = rotrFixed(right^work, 20U);
+    work = (left ^ right) & 0xffff0000;
+    left ^= work;
+
+    right = rotrFixed(right^work, 18U);
+    work = (left ^ right) & 0x33333333;
+    left ^= work;
+
+    right = rotrFixed(right^work, 6U);
+    work = (left ^ right) & 0x00ff00ff;
+    left ^= work;
+
+    right = rotlFixed(right^work, 9U);
+    work = (left ^ right) & 0xaaaaaaaa;
+    left = rotlFixed(left^work, 1U);
+    right ^= work;
+}
+
+static inline void FPERM(word32& left, word32& right)
+{
+    word32 work;
+
+    right = rotrFixed(right, 1U);
+    work = (left ^ right) & 0xaaaaaaaa;
+    right ^= work;
+    left = rotrFixed(left^work, 9U);
+    work = (left ^ right) & 0x00ff00ff;
+    right ^= work;
+    left = rotlFixed(left^work, 6U);
+    work = (left ^ right) & 0x33333333;
+    right ^= work;
+    left = rotlFixed(left^work, 18U);
+    work = (left ^ right) & 0xffff0000;
+    right ^= work;
+    left = rotlFixed(left^work, 20U);
+    work = (left ^ right) & 0xf0f0f0f0;
+    right ^= work;
+    left = rotrFixed(left^work, 4U);
+}
+
+
+void BasicDES::RawProcessBlock(word32& lIn, word32& rIn) const
 {
     word32 l = lIn, r = rIn;
     const word32* kptr = k_;
@@ -336,7 +350,7 @@ void DES::RawProcessBlock(word32& lIn, word32& rIn) const
 }
 
 
-void DES_BASE::Process(byte* out, const byte* in, word32 sz)
+void DES::Process(byte* out, const byte* in, word32 sz)
 {
     if (mode_ == ECB)
         ECB_Process(out, in, sz);
@@ -358,38 +372,24 @@ void DES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const
     Block::Get(in)(l)(r);
     IPERM(l,r);
 
-    const word32* kptr = k_;
-
-    for (unsigned i = 0; i < 8; i++)
-    {
-        word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
-        l ^= Spbox[6][(work) & 0x3f]
-          ^  Spbox[4][(work >> 8) & 0x3f]
-          ^  Spbox[2][(work >> 16) & 0x3f]
-          ^  Spbox[0][(work >> 24) & 0x3f];
-        work = r ^ kptr[4*i+1];
-        l ^= Spbox[7][(work) & 0x3f]
-          ^  Spbox[5][(work >> 8) & 0x3f]
-          ^  Spbox[3][(work >> 16) & 0x3f]
-          ^  Spbox[1][(work >> 24) & 0x3f];
-
-        work = rotrFixed(l, 4U) ^ kptr[4*i+2];
-        r ^= Spbox[6][(work) & 0x3f]
-          ^  Spbox[4][(work >> 8) & 0x3f]
-          ^  Spbox[2][(work >> 16) & 0x3f]
-          ^  Spbox[0][(work >> 24) & 0x3f];
-        work = l ^ kptr[4*i+3];
-        r ^= Spbox[7][(work) & 0x3f]
-          ^  Spbox[5][(work >> 8) & 0x3f]
-          ^  Spbox[3][(work >> 16) & 0x3f]
-          ^  Spbox[1][(work >> 24) & 0x3f];
-    }
+    RawProcessBlock(l, r);
 
     FPERM(l,r);
     Block::Put(xOr, out)(r)(l);
 }
 
 
+void DES_EDE2::Process(byte* out, const byte* in, word32 sz)
+{
+    if (mode_ == ECB)
+        ECB_Process(out, in, sz);
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            CBC_Encrypt(out, in, sz);
+        else
+            CBC_Decrypt(out, in, sz);
+}
+
 void DES_EDE2::SetKey(const byte* key, word32 sz, CipherDir dir)
 {
     des1_.SetKey(key, sz, dir);
@@ -403,9 +403,11 @@ void DES_EDE2::ProcessAndXorBlock(const byte* in, const byte* xOr,
     word32 l,r;
     Block::Get(in)(l)(r);
     IPERM(l,r);
+
     des1_.RawProcessBlock(l, r);
     des2_.RawProcessBlock(r, l);
     des1_.RawProcessBlock(l, r);
+
     FPERM(l,r);
     Block::Put(xOr, out)(r)(l);
 }
@@ -418,18 +420,389 @@ void DES_EDE3::SetKey(const byte* key, word32 sz, CipherDir dir)
     des3_.SetKey(key+(dir==DECRYPTION?0:2*8), sz, dir);
 }
 
+
+
+#if !defined(DO_DES_ASM)
+
+// Generic Version
+void DES_EDE3::Process(byte* out, const byte* in, word32 sz)
+{
+    if (mode_ == ECB)
+        ECB_Process(out, in, sz);
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            CBC_Encrypt(out, in, sz);
+        else
+            CBC_Decrypt(out, in, sz);
+}
+
+#else
+
+// ia32 optimized version
+void DES_EDE3::Process(byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / DES_BLOCK_SIZE;
+
+    if (mode_ == CBC)    
+        if (dir_ == ENCRYPTION)
+            while (blocks--) {
+                r_[0] ^= *(word32*)in;
+                r_[1] ^= *(word32*)(in + 4);
+
+                AsmProcess((byte*)r_, (byte*)r_, (void*)Spbox);
+                
+                memcpy(out, r_, DES_BLOCK_SIZE);
+
+                in  += DES_BLOCK_SIZE;
+                out += DES_BLOCK_SIZE;
+            }
+        else
+            while (blocks--) {
+                AsmProcess(in, out, (void*)Spbox);
+               
+                *(word32*)out       ^= r_[0];
+                *(word32*)(out + 4) ^= r_[1];
+
+                memcpy(r_, in, DES_BLOCK_SIZE);
+
+                out += DES_BLOCK_SIZE;
+                in  += DES_BLOCK_SIZE;
+            }
+    else
+        while (blocks--) {
+            AsmProcess(in, out, (void*)Spbox);
+           
+            out += DES_BLOCK_SIZE;
+            in  += DES_BLOCK_SIZE;
+        }
+}
+
+#endif // DO_DES_ASM
+
+
 void DES_EDE3::ProcessAndXorBlock(const byte* in, const byte* xOr,
                                   byte* out) const
 {
     word32 l,r;
     Block::Get(in)(l)(r);
     IPERM(l,r);
+
     des1_.RawProcessBlock(l, r);
     des2_.RawProcessBlock(r, l);
     des3_.RawProcessBlock(l, r);
+
     FPERM(l,r);
     Block::Put(xOr, out)(r)(l);
 }
 
 
+#if defined(DO_DES_ASM)
+
+/* Uses IPERM algorithm from above
+
+   left  is in eax
+   right is in ebx
+
+   uses ecx
+*/
+#define AsmIPERM() {\
+    AS2(    rol   ebx, 4                        )   \
+    AS2(    mov   ecx, eax                      )   \
+    AS2(    xor   ecx, ebx                      )   \
+    AS2(    and   ecx, 0xf0f0f0f0               )   \
+    AS2(    xor   ebx, ecx                      )   \
+    AS2(    xor   eax, ecx                      )   \
+    AS2(    ror   ebx, 20                       )   \
+    AS2(    mov   ecx, eax                      )   \
+    AS2(    xor   ecx, ebx                      )   \
+    AS2(    and   ecx, 0xffff0000               )   \
+    AS2(    xor   ebx, ecx                      )   \
+    AS2(    xor   eax, ecx                      )   \
+    AS2(    ror   ebx, 18                       )   \
+    AS2(    mov   ecx, eax                      )   \
+    AS2(    xor   ecx, ebx                      )   \
+    AS2(    and   ecx, 0x33333333               )   \
+    AS2(    xor   ebx, ecx                      )   \
+    AS2(    xor   eax, ecx                      )   \
+    AS2(    ror   ebx, 6                        )   \
+    AS2(    mov   ecx, eax                      )   \
+    AS2(    xor   ecx, ebx                      )   \
+    AS2(    and   ecx, 0x00ff00ff               )   \
+    AS2(    xor   ebx, ecx                      )   \
+    AS2(    xor   eax, ecx                      )   \
+    AS2(    rol   ebx, 9                        )   \
+    AS2(    mov   ecx, eax                      )   \
+    AS2(    xor   ecx, ebx                      )   \
+    AS2(    and   ecx, 0xaaaaaaaa               )   \
+    AS2(    xor   eax, ecx                      )   \
+    AS2(    rol   eax, 1                        )   \
+    AS2(    xor   ebx, ecx                      ) }
+
+
+/* Uses FPERM algorithm from above
+
+   left  is in eax
+   right is in ebx
+
+   uses ecx
+*/
+#define AsmFPERM()    {\
+    AS2(    ror  ebx, 1                     )    \
+    AS2(    mov  ecx, eax                   )    \
+    AS2(    xor  ecx, ebx                   )    \
+    AS2(    and  ecx, 0xaaaaaaaa            )    \
+    AS2(    xor  eax, ecx                   )    \
+    AS2(    xor  ebx, ecx                   )    \
+    AS2(    ror  eax, 9                     )    \
+    AS2(    mov  ecx, ebx                   )    \
+    AS2(    xor  ecx, eax                   )    \
+    AS2(    and  ecx, 0x00ff00ff            )    \
+    AS2(    xor  eax, ecx                   )    \
+    AS2(    xor  ebx, ecx                   )    \
+    AS2(    rol  eax, 6                     )    \
+    AS2(    mov  ecx, ebx                   )    \
+    AS2(    xor  ecx, eax                   )    \
+    AS2(    and  ecx, 0x33333333            )    \
+    AS2(    xor  eax, ecx                   )    \
+    AS2(    xor  ebx, ecx                   )    \
+    AS2(    rol  eax, 18                    )    \
+    AS2(    mov  ecx, ebx                   )    \
+    AS2(    xor  ecx, eax                   )    \
+    AS2(    and  ecx, 0xffff0000            )    \
+    AS2(    xor  eax, ecx                   )    \
+    AS2(    xor  ebx, ecx                   )    \
+    AS2(    rol  eax, 20                    )    \
+    AS2(    mov  ecx, ebx                   )    \
+    AS2(    xor  ecx, eax                   )    \
+    AS2(    and  ecx, 0xf0f0f0f0            )    \
+    AS2(    xor  eax, ecx                   )    \
+    AS2(    xor  ebx, ecx                   )    \
+    AS2(    ror  eax, 4                     ) }
+
+
+
+
+/* DesRound implements this algorithm:
+
+        word32 work = rotrFixed(r, 4U) ^ key[0];
+        l ^= Spbox[6][(work) & 0x3f]
+          ^  Spbox[4][(work >> 8) & 0x3f]
+          ^  Spbox[2][(work >> 16) & 0x3f]
+          ^  Spbox[0][(work >> 24) & 0x3f];
+        work = r ^ key[1];
+        l ^= Spbox[7][(work) & 0x3f]
+          ^  Spbox[5][(work >> 8) & 0x3f]
+          ^  Spbox[3][(work >> 16) & 0x3f]
+          ^  Spbox[1][(work >> 24) & 0x3f];
+
+        work = rotrFixed(l, 4U) ^ key[2];
+        r ^= Spbox[6][(work) & 0x3f]
+          ^  Spbox[4][(work >> 8) & 0x3f]
+          ^  Spbox[2][(work >> 16) & 0x3f]
+          ^  Spbox[0][(work >> 24) & 0x3f];
+        work = l ^ key[3];
+        r ^= Spbox[7][(work) & 0x3f]
+          ^  Spbox[5][(work >> 8) & 0x3f]
+          ^  Spbox[3][(work >> 16) & 0x3f]
+          ^  Spbox[1][(work >> 24) & 0x3f];
+
+   left  is in aex
+   right is in ebx
+   key   is in edx
+
+   edvances key for next round
+
+   uses ecx, esi, and edi
+*/
+#define DesRound() \
+    AS2(    mov   ecx,  ebx                     )\
+    AS2(    mov   esi,  DWORD PTR [edx]         )\
+    AS2(    ror   ecx,  4                       )\
+    AS2(    xor   ecx,  esi                     )\
+    AS2(    and   ecx,  0x3f3f3f3f              )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   eax,  [ebp + esi*4 + 6*256]   )\
+    AS2(    shr   ecx,  16                      )\
+    AS2(    xor   eax,  [ebp + edi*4 + 4*256]   )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   eax,  [ebp + esi*4 + 2*256]   )\
+    AS2(    mov   esi,  DWORD PTR [edx + 4]     )\
+    AS2(    xor   eax,  [ebp + edi*4]           )\
+    AS2(    mov   ecx,  ebx                     )\
+    AS2(    xor   ecx,  esi                     )\
+    AS2(    and   ecx,  0x3f3f3f3f              )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   eax,  [ebp + esi*4 + 7*256]   )\
+    AS2(    shr   ecx,  16                      )\
+    AS2(    xor   eax,  [ebp + edi*4 + 5*256]   )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   eax,  [ebp + esi*4 + 3*256]   )\
+    AS2(    mov   esi,  DWORD PTR [edx + 8]     )\
+    AS2(    xor   eax,  [ebp + edi*4 + 1*256]   )\
+    AS2(    mov   ecx,  eax                     )\
+    AS2(    ror   ecx,  4                       )\
+    AS2(    xor   ecx,  esi                     )\
+    AS2(    and   ecx,  0x3f3f3f3f              )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   ebx,  [ebp + esi*4 + 6*256]   )\
+    AS2(    shr   ecx,  16                      )\
+    AS2(    xor   ebx,  [ebp + edi*4 + 4*256]   )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   ebx,  [ebp + esi*4 + 2*256]   )\
+    AS2(    mov   esi,  DWORD PTR [edx + 12]    )\
+    AS2(    xor   ebx,  [ebp + edi*4]           )\
+    AS2(    mov   ecx,  eax                     )\
+    AS2(    xor   ecx,  esi                     )\
+    AS2(    and   ecx,  0x3f3f3f3f              )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   ebx,  [ebp + esi*4 + 7*256]   )\
+    AS2(    shr   ecx,  16                      )\
+    AS2(    xor   ebx,  [ebp + edi*4 + 5*256]   )\
+    AS2(    movzx esi,  cl                      )\
+    AS2(    movzx edi,  ch                      )\
+    AS2(    xor   ebx,  [ebp + esi*4 + 3*256]   )\
+    AS2(    add   edx,  16                      )\
+    AS2(    xor   ebx,  [ebp + edi*4 + 1*256]   )
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void DES_EDE3::AsmProcess(const byte* in, byte* out, void* box) const
+{
+#ifdef __GNUC__
+    #define AS1(x)    asm(#x);
+    #define AS2(x, y) asm(#x ", " #y);
+
+    asm(".intel_syntax noprefix");
+
+    #define PROLOG()  \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   edx, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   esi, DWORD PTR [ebp + 12]     )   \
+        AS2(    mov   ebp, DWORD PTR [ebp + 20]     )
+
+    // ebp restored at end
+    #define EPILOG()    \
+        AS2(    movd  edi, mm3                      )   \
+        AS2(    movd  ebx, mm4                      )   \
+        AS2(    movd  esi, mm5                      )   \
+        AS1(    emms                                )   \
+        asm(".att_syntax");
+
+#else
+    #define AS1(x)      __asm x
+    #define AS2(x, y)   __asm x, y
+
+    #define PROLOG()  \
+        AS1(    push  ebp                           )   \
+        AS2(    mov   ebp, esp                      )   \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   esi, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   edx, ecx                      )   \
+        AS2(    mov   ebp, DWORD PTR [ebp + 16]     )
+
+    // ebp restored at end
+    #define EPILOG() \
+        AS2(    movd  edi, mm3                      )   \
+        AS2(    movd  ebx, mm4                      )   \
+        AS2(    movd  esi, mm5                      )   \
+        AS2(    mov   esp, ebp                      )   \
+        AS1(    pop   ebp                           )   \
+        AS1(    emms                                )   \
+        AS1(    ret 12                              )
+
+#endif
+
+
+    PROLOG()
+
+    AS2(    movd  mm2, edx                      )
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    add   edx, 60                       )   // des1 = des1 key
+    #else
+        AS2(    add   edx, 56                       )   // des1 = des1 key
+    #endif
+
+    AS2(    mov   eax, DWORD PTR [esi]          )
+    AS2(    mov   ebx, DWORD PTR [esi + 4]      )
+    AS1(    bswap eax                           )    // left
+    AS1(    bswap ebx                           )    // right
+
+    AsmIPERM()
+
+    DesRound() // 1
+    DesRound() // 2
+    DesRound() // 3
+    DesRound() // 4
+    DesRound() // 5
+    DesRound() // 6
+    DesRound() // 7
+    DesRound() // 8
+
+    // swap left and right 
+    AS2(    xchg  eax, ebx                      )
+
+    DesRound() // 1
+    DesRound() // 2
+    DesRound() // 3
+    DesRound() // 4
+    DesRound() // 5
+    DesRound() // 6
+    DesRound() // 7
+    DesRound() // 8
+
+    // swap left and right
+    AS2(    xchg  eax, ebx                      )
+
+    DesRound() // 1
+    DesRound() // 2
+    DesRound() // 3
+    DesRound() // 4
+    DesRound() // 5
+    DesRound() // 6
+    DesRound() // 7
+    DesRound() // 8
+
+    AsmFPERM()
+
+    //end
+    AS2(    movd  ebp, mm6                      )
+
+    // swap and write out
+    AS1(    bswap ebx                           )
+    AS1(    bswap eax                           )
+
+#ifdef __GNUC__
+    AS2(    mov   esi, DWORD PTR [ebp +  16]    )   // outBlock
+#else
+    AS2(    mov   esi, DWORD PTR [ebp +  12]    )   // outBlock
+#endif
+
+    AS2(    mov   DWORD PTR [esi],     ebx      )   // right first
+    AS2(    mov   DWORD PTR [esi + 4], eax      )
+    
+
+    EPILOG()
+}
+
+
+
+#endif // defined(DO_DES_ASM)
+
+
 }  // namespace
diff --git a/extra/yassl/taocrypt/src/dh.cpp b/extra/yassl/taocrypt/src/dh.cpp
index ea1b5846f7d..44934394343 100644
--- a/extra/yassl/taocrypt/src/dh.cpp
+++ b/extra/yassl/taocrypt/src/dh.cpp
@@ -26,10 +26,26 @@
 #include "runtime.hpp"
 #include "dh.hpp"
 #include "asn.hpp"
+#include 
 
 namespace TaoCrypt {
 
 
+namespace {  // locals
+
+unsigned int DiscreteLogWorkFactor(unsigned int n)
+{
+    // assuming discrete log takes about the same time as factoring
+    if (n<5)
+        return 0;
+    else
+        return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) *
+                pow(log(double(n)), 2.0/3.0) - 5);
+}
+
+} // namespace locals
+
+
 // Generate a DH Key Pair
 void DH::GenerateKeyPair(RandomNumberGenerator& rng, byte* priv, byte* pub)
 {
@@ -41,7 +57,8 @@ void DH::GenerateKeyPair(RandomNumberGenerator& rng, byte* priv, byte* pub)
 // Generate private value
 void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
 {
-    Integer x(rng, Integer::One(), p_ - 1);
+    Integer x(rng, Integer::One(), mySTL::min(p_ - 1,
+        Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
     x.Encode(priv, p_.ByteCount());
 }
 
@@ -57,11 +74,16 @@ void DH::GeneratePublic(const byte* priv, byte* pub)
 
 
 // Generate Agreement
-void DH::Agree(byte* agree, const byte* priv, const byte* otherPub)
+void DH::Agree(byte* agree, const byte* priv, const byte* otherPub, word32
+               otherSz)
 {
     const word32 bc(p_.ByteCount());
     Integer x(priv, bc);
-    Integer y(otherPub, bc);
+    Integer y;
+    if (otherSz)
+        y.Decode(otherPub, otherSz);
+    else
+        y.Decode(otherPub, bc);
 
     Integer z(a_exp_b_mod_c(y, x, p_));
     z.Encode(agree, bc);
diff --git a/extra/yassl/taocrypt/src/hash.cpp b/extra/yassl/taocrypt/src/hash.cpp
index 53b1b489b14..4e783e2c3b1 100644
--- a/extra/yassl/taocrypt/src/hash.cpp
+++ b/extra/yassl/taocrypt/src/hash.cpp
@@ -39,6 +39,15 @@ HASHwithTransform::HASHwithTransform(word32 digSz, word32 buffSz)
 }
 
 
+void HASHwithTransform::AddLength(word32 len)
+{
+    HashLengthType tmp = loLen_;
+    if ( (loLen_ += len) < tmp)
+        hiLen_++;                       // carry low to high
+    hiLen_ += SafeRightShift<8*sizeof(HashLengthType)>(len);
+}
+
+
 // Update digest with data of size len, do in blocks
 void HASHwithTransform::Update(const byte* data, word32 len)
 {
@@ -57,6 +66,8 @@ void HASHwithTransform::Update(const byte* data, word32 len)
         if (buffLen_ == blockSz) {
             ByteReverseIf(local, local, blockSz, getByteOrder());
             Transform();
+            AddLength(blockSz);
+            buffLen_ = 0;
         }
     }
 }
@@ -69,25 +80,29 @@ void HASHwithTransform::Final(byte* hash)
     word32    digestSz  = getDigestSize();
     word32    padSz     = getPadSize();
     ByteOrder order     = getByteOrder();
-    word32    prePadLen = length_ + buffLen_ * 8;  // in bits
+
+    AddLength(buffLen_);                        // before adding pads
+    HashLengthType preLoLen = GetBitCountLo();
+    HashLengthType preHiLen = GetBitCountHi();
     byte*     local     = reinterpret_cast(buffer_);
 
     local[buffLen_++] = 0x80;  // add 1
 
     // pad with zeros
     if (buffLen_ > padSz) {
-        while (buffLen_ < blockSz) local[buffLen_++] = 0;
+        memset(&local[buffLen_], 0, blockSz - buffLen_);
+        buffLen_ += blockSz - buffLen_;
+
         ByteReverseIf(local, local, blockSz, order);
         Transform();
+        buffLen_ = 0;
     }
-    while (buffLen_ < padSz) local[buffLen_++] = 0;
+    memset(&local[buffLen_], 0, padSz - buffLen_);
 
     ByteReverseIf(local, local, blockSz, order);
     
-    word32 hiSize = 0;  // for future 64 bit length TODO:
-    memcpy(&local[padSz],   order ? &hiSize : &prePadLen, sizeof(prePadLen));
-    memcpy(&local[padSz+4], order ? &prePadLen : &hiSize, sizeof(prePadLen));
-
+    memcpy(&local[padSz],   order ? &preHiLen : &preLoLen, sizeof(preLoLen));
+    memcpy(&local[padSz+4], order ? &preLoLen : &preHiLen, sizeof(preLoLen));
 
     Transform();
     ByteReverseIf(digest_, digest_, digestSz, order);
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 4ade5491530..82a248ff7da 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -114,7 +114,7 @@ CPP_TYPENAME AllocatorBase::pointer AlignedAllocator::allocate(
         assert(IsAlignedOn(p, 16));
         return (T*)p;
     }
-    return new (tc) T[n];
+    return NEW_TC T[n];
 }
 
 
@@ -555,7 +555,7 @@ static word AtomicInverseModPower2(word A)
     for (unsigned i=3; i= BLOCK_SIZE) {
+                memcpy(&local[0], data, BLOCK_SIZE);
+
+                data     += BLOCK_SIZE;
+                len      -= BLOCK_SIZE;
+
+                ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder);
+                Transform();
+                AddLength(BLOCK_SIZE);
+            }
+        #else
+            word32 times = len / BLOCK_SIZE;
+            if (times) {
+                AsmTransform(data, times);
+                const word32 add = BLOCK_SIZE * times;
+                AddLength(add);
+                len  -= add;
+                data += add;
+            }
+        #endif
+    }
+
+    // cache any data left
+    if (len) {
+        memcpy(&local[buffLen_], data, len);
+        buffLen_ += len;
+    }
+}
+
+
+#ifdef DO_MD5_ASM
+
+
+/*
+    // w = rotlFixed(w + f(x, y, z) + index[edi] + data, s) + x
+#define ASMMD5STEP(f, w, x, y, z, index, data, s)       \
+    f(x, y, z)                                          \
+    AS2(    mov   ebp, [edi + index * 4]            )   \
+    AS2(    lea     w, [esi + w + data]             )   \
+    AS2(    add     w, ebp                          )   \
+    AS2(    rol     w, s                            )   \
+    AS2(    add     w, x                            )
+
+
+    // F1(x, y, z) (z ^ (x & (y ^ z)))
+    // place in esi
+#define ASMF1(x, y, z) \
+    AS2(    mov   esi, y                )   \
+    AS2(    xor   esi, z                )   \
+    AS2(    and   esi, x                )   \
+    AS2(    xor   esi, z                )
+
+
+#define ASMF2(x, y, z) ASMF1(z, x, y)
+
+
+    // F3(x ^ y ^ z)
+    // place in esi
+#define ASMF3(x, y, z)  \
+    AS2(    mov   esi, x                )   \
+    AS2(    xor   esi, y                )   \
+    AS2(    xor   esi, z                )
+
+
+
+    // F4(x, y, z) (y ^ (x | ~z))
+    // place in esi
+#define ASMF4(x, y, z)  \
+    AS2(    mov   esi, z                )   \
+    AS1(    not   esi                   )   \
+    AS2(     or   esi, x                )   \
+    AS2(    xor   esi, y                )
+*/
+
+
+    // combine above ASMMD5STEP(f w/ each f ASMF1 - F4
+
+    // esi already set up, after using set for next round
+    // ebp already set up, set up using next round index
+    
+#define MD5STEP1(w, x, y, z, index, data, s)    \
+    AS2(    xor   esi, z                    )   \
+    AS2(    and   esi, x                    )   \
+    AS2(    lea     w, [ebp + w + data]     )   \
+    AS2(    xor   esi, z                    )   \
+    AS2(    add     w, esi                  )   \
+    AS2(    mov   esi, x                    )   \
+    AS2(    rol     w, s                    )   \
+    AS2(    mov   ebp, [edi + index * 4]    )   \
+    AS2(    add     w, x                    )
+
+#define MD5STEP2(w, x, y, z, index, data, s)    \
+    AS2(    xor   esi, x                    )   \
+    AS2(    and   esi, z                    )   \
+    AS2(    lea     w, [ebp + w + data]     )   \
+    AS2(    xor   esi, y                    )   \
+    AS2(    add     w, esi                  )   \
+    AS2(    mov   esi, x                    )   \
+    AS2(    rol     w, s                    )   \
+    AS2(    mov   ebp, [edi + index * 4]    )   \
+    AS2(    add     w, x                    )
+
+
+#define MD5STEP3(w, x, y, z, index, data, s)    \
+    AS2(    xor   esi, z                    )   \
+    AS2(    lea     w, [ebp + w + data]     )   \
+    AS2(    xor   esi, x                    )   \
+    AS2(    add     w, esi                  )   \
+    AS2(    mov   esi, x                    )   \
+    AS2(    rol     w, s                    )   \
+    AS2(    mov   ebp, [edi + index * 4]    )   \
+    AS2(    add     w, x                    )
+
+
+#define MD5STEP4(w, x, y, z, index, data, s)    \
+    AS2(     or   esi, x                    )   \
+    AS2(    lea     w, [ebp + w + data]     )   \
+    AS2(    xor   esi, y                    )   \
+    AS2(    add     w, esi                  )   \
+    AS2(    mov   esi, y                    )   \
+    AS2(    rol     w, s                    )   \
+    AS1(    not   esi                       )   \
+    AS2(    mov   ebp, [edi + index * 4]    )   \
+    AS2(    add     w, x                    )
+
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void MD5::AsmTransform(const byte* data, word32 times)
+{
+#ifdef __GNUC__
+    #define AS1(x)    asm(#x);
+    #define AS2(x, y) asm(#x ", " #y);
+
+    #define PROLOG()  \
+        asm(".intel_syntax noprefix"); \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   edi, DWORD PTR [ebp + 12]     )   \
+        AS2(    mov   eax, DWORD PTR [ebp + 16]     )
+
+    #define EPILOG()  \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS1(    emms                            )   \
+        asm(".att_syntax");
+#else
+    #define AS1(x)    __asm x
+    #define AS2(x, y) __asm x, y
+
+    #define PROLOG() \
+        AS1(    push  ebp                       )   \
+        AS2(    mov   ebp, esp                  )   \
+        AS2(    movd  mm3, edi                  )   \
+        AS2(    movd  mm4, ebx                  )   \
+        AS2(    movd  mm5, esi                  )   \
+        AS2(    movd  mm6, ebp                  )   \
+        AS2(    mov   edi, DWORD PTR [ebp +  8] )   \
+        AS2(    mov   eax, DWORD PTR [ebp + 12] )
+
+    #define EPILOG() \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS1(    pop   ebp                       )   \
+        AS1(    emms                            )   \
+        AS1(    ret  8                          )
+        
+#endif
+
+
+    PROLOG()
+
+    AS2(    mov   esi, ecx              )
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    add   esi, 20               )   // digest_[0]
+    #else
+        AS2(    add   esi, 16               )   // digest_[0]
+    #endif
+
+    AS2(    movd  mm2, eax              )   // store times_
+    AS2(    movd  mm1, esi              )   // store digest_
+    
+    AS2(    mov   eax, [esi]            )   // a
+    AS2(    mov   ebx, [esi +  4]       )   // b
+    AS2(    mov   ecx, [esi +  8]       )   // c
+    AS2(    mov   edx, [esi + 12]       )   // d
+  
+AS1(loopStart:)
+
+    // set up
+    AS2(    mov   esi, ecx      )
+    AS2(    mov   ebp, [edi]    )
+
+    MD5STEP1( eax, ebx, ecx, edx, 1,   0xd76aa478,  7)
+    MD5STEP1( edx, eax, ebx, ecx, 2,   0xe8c7b756, 12)
+    MD5STEP1( ecx, edx, eax, ebx, 3,   0x242070db, 17)
+    MD5STEP1( ebx, ecx, edx, eax, 4,   0xc1bdceee, 22)
+    MD5STEP1( eax, ebx, ecx, edx, 5,   0xf57c0faf,  7)
+    MD5STEP1( edx, eax, ebx, ecx, 6,   0x4787c62a, 12)
+    MD5STEP1( ecx, edx, eax, ebx, 7,   0xa8304613, 17)
+    MD5STEP1( ebx, ecx, edx, eax, 8,   0xfd469501, 22)
+    MD5STEP1( eax, ebx, ecx, edx, 9,   0x698098d8,  7)
+    MD5STEP1( edx, eax, ebx, ecx, 10,  0x8b44f7af, 12)
+    MD5STEP1( ecx, edx, eax, ebx, 11,  0xffff5bb1, 17)
+    MD5STEP1( ebx, ecx, edx, eax, 12,  0x895cd7be, 22)
+    MD5STEP1( eax, ebx, ecx, edx, 13,  0x6b901122,  7)
+    MD5STEP1( edx, eax, ebx, ecx, 14,  0xfd987193, 12)
+    MD5STEP1( ecx, edx, eax, ebx, 15,  0xa679438e, 17)
+    MD5STEP1( ebx, ecx, edx, eax, 1,   0x49b40821, 22)
+
+    MD5STEP2( eax, ebx, ecx, edx, 6,  0xf61e2562,  5)
+    MD5STEP2( edx, eax, ebx, ecx, 11, 0xc040b340,  9)
+    MD5STEP2( ecx, edx, eax, ebx, 0,  0x265e5a51, 14)
+    MD5STEP2( ebx, ecx, edx, eax, 5,  0xe9b6c7aa, 20)
+    MD5STEP2( eax, ebx, ecx, edx, 10, 0xd62f105d,  5)
+    MD5STEP2( edx, eax, ebx, ecx, 15, 0x02441453,  9)
+    MD5STEP2( ecx, edx, eax, ebx, 4,  0xd8a1e681, 14)
+    MD5STEP2( ebx, ecx, edx, eax, 9,  0xe7d3fbc8, 20)
+    MD5STEP2( eax, ebx, ecx, edx, 14, 0x21e1cde6,  5)
+    MD5STEP2( edx, eax, ebx, ecx, 3,  0xc33707d6,  9)
+    MD5STEP2( ecx, edx, eax, ebx, 8,  0xf4d50d87, 14)
+    MD5STEP2( ebx, ecx, edx, eax, 13, 0x455a14ed, 20)
+    MD5STEP2( eax, ebx, ecx, edx, 2,  0xa9e3e905,  5)
+    MD5STEP2( edx, eax, ebx, ecx, 7,  0xfcefa3f8,  9)
+    MD5STEP2( ecx, edx, eax, ebx, 12, 0x676f02d9, 14)
+    MD5STEP2( ebx, ecx, edx, eax, 5,  0x8d2a4c8a, 20)
+
+    MD5STEP3(  eax, ebx, ecx, edx, 8,   0xfffa3942,  4)
+    MD5STEP3(  edx, eax, ebx, ecx, 11,  0x8771f681, 11)
+    MD5STEP3(  ecx, edx, eax, ebx, 14,  0x6d9d6122, 16)
+    MD5STEP3(  ebx, ecx, edx, eax, 1,   0xfde5380c, 23)
+    MD5STEP3(  eax, ebx, ecx, edx, 4,   0xa4beea44,  4)
+    MD5STEP3(  edx, eax, ebx, ecx, 7,   0x4bdecfa9, 11)
+    MD5STEP3(  ecx, edx, eax, ebx, 10,  0xf6bb4b60, 16)
+    MD5STEP3(  ebx, ecx, edx, eax, 13,  0xbebfbc70, 23)
+    MD5STEP3(  eax, ebx, ecx, edx, 0,   0x289b7ec6,  4)
+    MD5STEP3(  edx, eax, ebx, ecx, 3,   0xeaa127fa, 11)
+    MD5STEP3(  ecx, edx, eax, ebx, 6,   0xd4ef3085, 16)
+    MD5STEP3(  ebx, ecx, edx, eax, 9,   0x04881d05, 23)
+    MD5STEP3(  eax, ebx, ecx, edx, 12,  0xd9d4d039,  4)
+    MD5STEP3(  edx, eax, ebx, ecx, 15,  0xe6db99e5, 11)
+    MD5STEP3(  ecx, edx, eax, ebx, 2,   0x1fa27cf8, 16)
+    MD5STEP3(  ebx, ecx, edx, eax, 0,   0xc4ac5665, 23)
+
+    // setup
+    AS2(    mov   esi, edx      )
+    AS1(    not   esi           )
+
+    MD5STEP4(  eax, ebx, ecx, edx, 7,   0xf4292244,  6)
+    MD5STEP4(  edx, eax, ebx, ecx, 14,  0x432aff97, 10)
+    MD5STEP4(  ecx, edx, eax, ebx, 5,   0xab9423a7, 15)
+    MD5STEP4(  ebx, ecx, edx, eax, 12,  0xfc93a039, 21)
+    MD5STEP4(  eax, ebx, ecx, edx, 3,   0x655b59c3,  6)
+    MD5STEP4(  edx, eax, ebx, ecx, 10,  0x8f0ccc92, 10)
+    MD5STEP4(  ecx, edx, eax, ebx, 1,   0xffeff47d, 15)
+    MD5STEP4(  ebx, ecx, edx, eax, 8,   0x85845dd1, 21)
+    MD5STEP4(  eax, ebx, ecx, edx, 15,  0x6fa87e4f,  6)
+    MD5STEP4(  edx, eax, ebx, ecx, 6,   0xfe2ce6e0, 10)
+    MD5STEP4(  ecx, edx, eax, ebx, 13,  0xa3014314, 15)
+    MD5STEP4(  ebx, ecx, edx, eax, 4,   0x4e0811a1, 21)
+    MD5STEP4(  eax, ebx, ecx, edx, 11,  0xf7537e82,  6)
+    MD5STEP4(  edx, eax, ebx, ecx, 2,   0xbd3af235, 10)
+    MD5STEP4(  ecx, edx, eax, ebx, 9,   0x2ad7d2bb, 15)
+    MD5STEP4(  ebx, ecx, edx, eax, 9,   0xeb86d391, 21)
+    
+    AS2(    movd  esi, mm1              )   // digest_
+
+    AS2(    add   [esi],      eax       )   // write out
+    AS2(    add   [esi +  4], ebx       )
+    AS2(    add   [esi +  8], ecx       )
+    AS2(    add   [esi + 12], edx       )
+
+    AS2(    add   edi, 64               )
+
+    AS2(    mov   eax, [esi]            )
+    AS2(    mov   ebx, [esi +  4]       )
+    AS2(    mov   ecx, [esi +  8]       )
+    AS2(    mov   edx, [esi + 12]       )
+
+    AS2(    movd  ebp, mm2              )   // times
+    AS1(    dec   ebp                   )
+    AS2(    movd  mm2, ebp              )
+    AS1(    jnz   loopStart             )
+
+
+    EPILOG()
+}
+
+
+#endif // DO_MD5_ASM
+
+
 void MD5::Transform()
 {
 #define F1(x, y, z) (z ^ (x & (y ^ z)))
@@ -161,10 +498,8 @@ void MD5::Transform()
 
     // Wipe variables
     a = b = c = d = 0;
-
-    buffLen_ = 0;
-    length_ += 512;
 }
 
+
 } // namespace
 
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index 0b33bb38aea..3d0539187a7 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -25,60 +25,59 @@
 #include "runtime.hpp"
 #include "misc.hpp"
 
-
-void* operator new(size_t sz, TaoCrypt::new_t)
-{
 #ifdef YASSL_PURE_C
+
+    void* operator new(size_t sz, TaoCrypt::new_t)
+    {
     void* ptr = malloc(sz ? sz : 1);
     if (!ptr) abort();
 
     return ptr;
-#else
-    return ::operator new(sz);
-#endif
-}
+    }
 
 
-void operator delete(void* ptr, TaoCrypt::new_t)
-{
-#ifdef YASSL_PURE_C
+    void operator delete(void* ptr, TaoCrypt::new_t)
+    {
     if (ptr) free(ptr);
-#else
-    ::operator delete(ptr);
-#endif
-}
+    }
 
 
-void* operator new[](size_t sz, TaoCrypt::new_t nt)
-{
+    void* operator new[](size_t sz, TaoCrypt::new_t nt)
+    {
     return ::operator new(sz, nt);
-}
+    }
 
 
-void operator delete[](void* ptr, TaoCrypt::new_t nt)
-{
+    void operator delete[](void* ptr, TaoCrypt::new_t nt)
+    {
     ::operator delete(ptr, nt);
-}
+    }
 
 
-/* uncomment to test
-// make sure not using globals anywhere by forgetting to use overloaded
-void* operator new(size_t sz);
+    /* uncomment to test
+    // make sure not using globals anywhere by forgetting to use overloaded
+    void* operator new(size_t sz);
 
-void operator delete(void* ptr);
+    void operator delete(void* ptr);
 
-void* operator new[](size_t sz);
+    void* operator new[](size_t sz);
 
-void operator delete[](void* ptr);
-*/
+    void operator delete[](void* ptr);
+    */
+
+
+    namespace TaoCrypt {
+
+        new_t tc;   // for library new
+
+    }
+
+#endif // YASSL_PURE_C
 
 
 namespace TaoCrypt {
 
 
-new_t tc;   // for library new
-
-
 inline void XorWords(word* r, const word* a, unsigned int n)
 {
     for (unsigned int i=0; i
+
 
 #if defined(_WIN32)
     #define _WIN32_WINNT 0x0400
@@ -52,6 +54,7 @@ RandomNumberGenerator::RandomNumberGenerator()
 // place a generated block in output
 void RandomNumberGenerator::GenerateBlock(byte* output, word32 sz)
 {
+    memset(output, 0, sz);
     cipher_.Process(output, output, sz);
 }
 
@@ -94,10 +97,9 @@ void OS_Seed::GenerateSeed(byte* output, word32 sz)
 OS_Seed::OS_Seed() 
 {
     fd_ = open("/dev/urandom",O_RDONLY);
+    if (fd_ == -1) {
+        fd_ = open("/dev/random",O_RDONLY);
     if (fd_ == -1)
-    {
-      fd_ = open("/dev/random",O_RDONLY);
-      if (fd_ == -1)
         error_.SetError(OPEN_RAN_E);
     }
 }
diff --git a/extra/yassl/taocrypt/src/ripemd.cpp b/extra/yassl/taocrypt/src/ripemd.cpp
index 0534a0d572d..da96b6cc1b4 100644
--- a/extra/yassl/taocrypt/src/ripemd.cpp
+++ b/extra/yassl/taocrypt/src/ripemd.cpp
@@ -26,6 +26,12 @@
 #include "ripemd.hpp"
 #include "algorithm.hpp"    // mySTL::swap
 
+
+
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_RIPEMD_ASM
+#endif
+
 namespace TaoCrypt {
 
 void RIPEMD160::Init()
@@ -37,7 +43,8 @@ void RIPEMD160::Init()
     digest_[4] = 0xc3d2e1f0L;
 
     buffLen_ = 0;
-    length_  = 0;
+    loLen_  = 0;
+    hiLen_  = 0;
 }
 
 
@@ -45,7 +52,8 @@ RIPEMD160::RIPEMD160(const RIPEMD160& that)
     : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE) 
 { 
     buffLen_ = that.buffLen_;
-    length_  = that.length_;
+    loLen_   = that.loLen_;
+    hiLen_   = that.hiLen_;
 
     memcpy(digest_, that.digest_, DIGEST_SIZE);
     memcpy(buffer_, that.buffer_, BLOCK_SIZE);
@@ -63,7 +71,8 @@ RIPEMD160& RIPEMD160::operator= (const RIPEMD160& that)
 
 void RIPEMD160::Swap(RIPEMD160& other)
 {
-    mySTL::swap(length_,  other.length_);
+    mySTL::swap(loLen_,   other.loLen_);
+    mySTL::swap(hiLen_,   other.hiLen_);
     mySTL::swap(buffLen_, other.buffLen_);
 
     memcpy(digest_, other.digest_, DIGEST_SIZE);
@@ -71,6 +80,61 @@ void RIPEMD160::Swap(RIPEMD160& other)
 }
 
 
+// Update digest with data of size len, do in blocks
+void RIPEMD160::Update(const byte* data, word32 len)
+{
+    byte* local = (byte*)buffer_;
+
+    // remove buffered data if possible
+    if (buffLen_)  {   
+        word32 add = min(len, BLOCK_SIZE - buffLen_);
+        memcpy(&local[buffLen_], data, add);
+
+        buffLen_ += add;
+        data     += add;
+        len      -= add;
+
+        if (buffLen_ == BLOCK_SIZE) {
+            ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder);
+            Transform();
+            AddLength(BLOCK_SIZE);
+            buffLen_ = 0;
+        }
+    }
+
+    // do block size transforms or all at once for asm
+    if (buffLen_ == 0) {
+        #ifndef DO_RIPEMD_ASM
+            while (len >= BLOCK_SIZE) {
+                memcpy(&local[0], data, BLOCK_SIZE);
+
+                data     += BLOCK_SIZE;
+                len      -= BLOCK_SIZE;
+
+                ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder);
+                Transform();
+                AddLength(BLOCK_SIZE);
+            }
+        #else
+            word32 times = len / BLOCK_SIZE;
+            if (times) {
+                AsmTransform(data, times);
+                const word32 add = BLOCK_SIZE * times;
+                AddLength(add);
+                len  -= add;
+                data += add;
+            }
+        #endif
+    }
+
+    // cache any data left
+    if (len) {
+        memcpy(&local[buffLen_], data, len);
+        buffLen_ += len;
+    }
+}
+
+
 // for all
 #define F(x, y, z)    (x ^ y ^ z) 
 #define G(x, y, z)    (z ^ (x & (y^z)))
@@ -79,14 +143,14 @@ void RIPEMD160::Swap(RIPEMD160& other)
 #define J(x, y, z)    (x ^ (y | ~z))
 
 #define k0 0
-#define k1 0x5a827999UL
-#define k2 0x6ed9eba1UL
-#define k3 0x8f1bbcdcUL
-#define k4 0xa953fd4eUL
-#define k5 0x50a28be6UL
-#define k6 0x5c4dd124UL
-#define k7 0x6d703ef3UL
-#define k8 0x7a6d76e9UL
+#define k1 0x5a827999
+#define k2 0x6ed9eba1
+#define k3 0x8f1bbcdc
+#define k4 0xa953fd4e
+#define k5 0x50a28be6
+#define k6 0x5c4dd124
+#define k7 0x6d703ef3
+#define k8 0x7a6d76e9
 #define k9 0
 
 // for 160 and 320
@@ -281,10 +345,495 @@ void RIPEMD160::Transform()
     digest_[3] = digest_[4] + a1 + b2;
     digest_[4] = digest_[0] + b1 + c2;
     digest_[0] = c1;
-
-    buffLen_ = 0;
-    length_ += 512;
 }
 
 
+#ifdef DO_RIPEMD_ASM
+
+/*
+    // F(x ^ y ^ z)
+    // place in esi
+#define ASMF(x, y, z)  \
+    AS2(    mov   esi, x                )   \
+    AS2(    xor   esi, y                )   \
+    AS2(    xor   esi, z                )
+
+
+    // G(z ^ (x & (y^z)))
+    // place in esi
+#define ASMG(x, y, z)  \
+    AS2(    mov   esi, z                )   \
+    AS2(    xor   esi, y                )   \
+    AS2(    and   esi, x                )   \
+    AS2(    xor   esi, z                )
+
+    
+    // H(z ^ (x | ~y))
+    // place in esi
+#define ASMH(x, y, z) \
+    AS2(    mov   esi, y                )   \
+    AS1(    not   esi                   )   \
+    AS2(     or   esi, x                )   \
+    AS2(    xor   esi, z                )
+
+
+    // I(y ^ (z & (x^y)))
+    // place in esi
+#define ASMI(x, y, z)  \
+    AS2(    mov   esi, y                )   \
+    AS2(    xor   esi, x                )   \
+    AS2(    and   esi, z                )   \
+    AS2(    xor   esi, y                )
+
+
+    // J(x ^ (y | ~z)))
+    // place in esi
+#define ASMJ(x, y, z)   \
+    AS2(    mov   esi, z                )   \
+    AS1(    not   esi                   )   \
+    AS2(     or   esi, y                )   \
+    AS2(    xor   esi, x                )
+
+
+// for 160 and 320
+// #define ASMSubround(f, a, b, c, d, e, i, s, k) 
+//    a += f(b, c, d) + data[i] + k;
+//    a = rotlFixed((word32)a, s) + e;
+//    c = rotlFixed((word32)c, 10U)
+
+#define ASMSubround(f, a, b, c, d, e, index, s, k) \
+    // a += f(b, c, d) + data[i] + k                    \
+    AS2(    mov   esp, [edi + index * 4]            )   \
+    f(b, c, d)                                          \
+    AS2(    add   esi, k                            )   \
+    AS2(    add   esi, esp                          )   \
+    AS2(    add     a, esi                          )   \
+    // a = rotlFixed((word32)a, s) + e                  \
+    AS2(    rol     a, s                            )   \
+    AS2(    rol     c, 10                           )   \
+    // c = rotlFixed((word32)c, 10U)                    \
+    AS2(    add     a, e                            )
+*/
+
+
+// combine F into subround w/ setup
+// esi already has c, setup for next round when done
+// esp already has edi[index], setup for next round when done
+
+#define ASMSubroundF(a, b, c, d, e, index, s) \
+    /* a += (b ^ c ^ d) + data[i] + k  */               \
+    AS2(    xor   esi, b                            )   \
+    AS2(    add     a, [edi + index * 4]            )   \
+    AS2(    xor   esi, d                            )   \
+    AS2(    add     a, esi                          )   \
+    /* a = rotlFixed((word32)a, s) + e */               \
+    AS2(    mov   esi, b                            )   \
+    AS2(    rol     a, s                            )   \
+    /* c = rotlFixed((word32)c, 10U) */                 \
+    AS2(    rol     c, 10                           )   \
+    AS2(    add     a, e                            )
+
+
+// combine G into subround w/ setup
+// esi already has c, setup for next round when done
+// esp already has edi[index], setup for next round when done
+
+#define ASMSubroundG(a, b, c, d, e, index, s, k) \
+    /* a += (d ^ (b & (c^d))) + data[i] + k  */         \
+    AS2(    xor   esi, d                            )   \
+    AS2(    and   esi, b                            )   \
+    AS2(    add     a, [edi + index * 4]            )   \
+    AS2(    xor   esi, d                            )   \
+    AS2(    lea     a, [esi + a + k]                )   \
+    /* a = rotlFixed((word32)a, s) + e */               \
+    AS2(    mov   esi, b                            )   \
+    AS2(    rol     a, s                            )   \
+    /* c = rotlFixed((word32)c, 10U) */                 \
+    AS2(    rol     c, 10                           )   \
+    AS2(    add     a, e                            )
+
+
+// combine H into subround w/ setup
+// esi already has c, setup for next round when done
+// esp already has edi[index], setup for next round when done
+
+#define ASMSubroundH(a, b, c, d, e, index, s, k) \
+    /* a += (d ^ (b | ~c)) + data[i] + k  */            \
+    AS1(    not   esi                               )   \
+    AS2(     or   esi, b                            )   \
+    AS2(    add     a, [edi + index * 4]            )   \
+    AS2(    xor   esi, d                            )   \
+    AS2(    lea     a, [esi + a + k]                )   \
+    /* a = rotlFixed((word32)a, s) + e */               \
+    AS2(    mov   esi, b                            )   \
+    AS2(    rol     a, s                            )   \
+    /* c = rotlFixed((word32)c, 10U) */                 \
+    AS2(    rol     c, 10                           )   \
+    AS2(    add     a, e                            )
+
+
+// combine I into subround w/ setup
+// esi already has c, setup for next round when done
+// esp already has edi[index], setup for next round when done
+
+#define ASMSubroundI(a, b, c, d, e, index, s, k) \
+    /* a += (c ^ (d & (b^c))) + data[i] + k  */         \
+    AS2(    xor   esi, b                            )   \
+    AS2(    and   esi, d                            )   \
+    AS2(    add     a, [edi + index * 4]            )   \
+    AS2(    xor   esi, c                            )   \
+    AS2(    lea     a, [esi + a + k]                )   \
+    /* a = rotlFixed((word32)a, s) + e */               \
+    AS2(    mov   esi, b                            )   \
+    AS2(    rol     a, s                            )   \
+    /* c = rotlFixed((word32)c, 10U) */                 \
+    AS2(    rol     c, 10                           )   \
+    AS2(    add     a, e                            )
+
+
+// combine J into subround w/ setup
+// esi already has d, setup for next round when done
+// esp already has edi[index], setup for next round when done
+
+#define ASMSubroundJ(a, b, c, d, e, index, s, k) \
+    /* a += (b ^ (c | ~d))) + data[i] + k  */           \
+    AS1(    not   esi                               )   \
+    AS2(     or   esi, c                            )   \
+    /* c = rotlFixed((word32)c, 10U) */                 \
+    AS2(    add     a, [edi + index * 4]            )   \
+    AS2(    xor   esi, b                            )   \
+    AS2(    rol     c, 10                           )   \
+    AS2(    lea     a, [esi + a + k]                )   \
+    /* a = rotlFixed((word32)a, s) + e */               \
+    AS2(    rol     a, s                            )   \
+    AS2(    mov   esi, c                            )   \
+    AS2(    add     a, e                            )
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void RIPEMD160::AsmTransform(const byte* data, word32 times)
+{
+#ifdef __GNUC__
+    #define AS1(x)    asm(#x);
+    #define AS2(x, y) asm(#x ", " #y);
+
+    #define PROLOG()  \
+        asm(".intel_syntax noprefix"); \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   edi, DWORD PTR [ebp + 12]     )   \
+        AS2(    mov   edx, DWORD PTR [ebp + 16]     )
+
+    #define EPILOG()  \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS1(    emms                            )   \
+        asm(".att_syntax");
+#else
+    #define AS1(x)    __asm x
+    #define AS2(x, y) __asm x, y
+
+    #define PROLOG() \
+        AS1(    push  ebp                       )   \
+        AS2(    mov   ebp, esp                  )   \
+        AS2(    movd  mm3, edi                  )   \
+        AS2(    movd  mm4, ebx                  )   \
+        AS2(    movd  mm5, esi                  )   \
+        AS2(    movd  mm6, ebp                  )   \
+        AS2(    mov   edi, DWORD PTR [ebp +  8] )   \
+        AS2(    mov   edx, DWORD PTR [ebp + 12] )
+
+    #define EPILOG() \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS1(    pop   ebp                       )   \
+        AS1(    emms                            )   \
+        AS1(    ret   8                         )
+        
+#endif
+
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    lea   esi, [ecx + 20]               )   // digest_[0]
+    #else
+        AS2(    lea   esi, [ecx + 16]               )   // digest_[0]
+    #endif
+
+    AS2(    sub   esp, 24               )   // make room for tmp a1 - e1
+    AS2(    movd  mm1, esi              )   // store digest_
+    
+AS1( loopStart: )
+
+    AS2(    movd  mm2, edx              )   // store times_
+
+    AS2(    mov   eax, [esi]            )   // a1
+    AS2(    mov   ebx, [esi +  4]       )   // b1
+    AS2(    mov   ecx, [esi +  8]       )   // c1
+    AS2(    mov   edx, [esi + 12]       )   // d1
+    AS2(    mov   ebp, [esi + 16]       )   // e1
+
+    // setup 
+    AS2(    mov   esi, ecx      )
+
+    ASMSubroundF( eax, ebx, ecx, edx, ebp,  0, 11)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx,  1, 14)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx,  2, 15)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx,  3, 12)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax,  4,  5)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp,  5,  8)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx,  6,  7)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx,  7,  9)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx,  8, 11)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax,  9, 13)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp, 10, 14)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx, 11, 15)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx, 12,  6)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx, 13,  7)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax, 14,  9)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp, 15,  8)
+
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  7,  7, k1)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx,  4,  6, k1)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx, 13,  8, k1)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax,  1, 13, k1)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp, 10, 11, k1)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  6,  9, k1)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx, 15,  7, k1)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx,  3, 15, k1)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax, 12,  7, k1)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp,  0, 12, k1)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  9, 15, k1)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx,  5,  9, k1)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx,  2, 11, k1)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax, 14,  7, k1)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp, 11, 13, k1)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  8, 12, k1)
+
+    ASMSubroundH( edx, ebp, eax, ebx, ecx,  3, 11, k2)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx, 10, 13, k2)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax, 14,  6, k2)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp,  4,  7, k2)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  9, 14, k2)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 15,  9, k2)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx,  8, 13, k2)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax,  1, 15, k2)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp,  2, 14, k2)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  7,  8, k2)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx,  0, 13, k2)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx,  6,  6, k2)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax, 13,  5, k2)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp, 11, 12, k2)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  5,  7, k2)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 12,  5, k2)
+
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  1, 11, k3)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax,  9, 12, k3)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp, 11, 14, k3)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx, 10, 15, k3)
+    ASMSubroundI( edx, ebp, eax, ebx, ecx,  0, 14, k3)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  8, 15, k3)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax, 12,  9, k3)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp,  4,  8, k3)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx, 13,  9, k3)
+    ASMSubroundI( edx, ebp, eax, ebx, ecx,  3, 14, k3)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  7,  5, k3)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax, 15,  6, k3)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp, 14,  8, k3)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx,  5,  6, k3)
+    ASMSubroundI( edx, ebp, eax, ebx, ecx,  6,  5, k3)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  2, 12, k3)
+
+    // setup
+    AS2(    mov   esi, ebp      )
+
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax,  4,  9, k4)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp,  0, 15, k4)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx,  5,  5, k4)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx,  9, 11, k4)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx,  7,  6, k4)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax, 12,  8, k4)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp,  2, 13, k4)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx, 10, 12, k4)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx, 14,  5, k4)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx,  1, 12, k4)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax,  3, 13, k4)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp,  8, 14, k4)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx, 11, 11, k4)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx,  6,  8, k4)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx, 15,  5, k4)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax, 13,  6, k4)
+
+    // store a1 - e1 on stack
+    AS2(    movd  esi, mm1              )   // digest_
+
+    AS2(    mov   [esp],      eax       )
+    AS2(    mov   [esp +  4], ebx       )
+    AS2(    mov   [esp +  8], ecx       )
+    AS2(    mov   [esp + 12], edx       )
+    AS2(    mov   [esp + 16], ebp       )
+
+    AS2(    mov   eax, [esi]            )   // a2
+    AS2(    mov   ebx, [esi +  4]       )   // b2
+    AS2(    mov   ecx, [esi +  8]       )   // c2
+    AS2(    mov   edx, [esi + 12]       )   // d2
+    AS2(    mov   ebp, [esi + 16]       )   // e2
+
+
+    // setup
+    AS2(    mov   esi, edx      )
+
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp,  5,  8, k5)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx, 14,  9, k5)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx,  7,  9, k5)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx,  0, 11, k5)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax,  9, 13, k5)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp,  2, 15, k5)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx, 11, 15, k5)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx,  4,  5, k5)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx, 13,  7, k5)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax,  6,  7, k5)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp, 15,  8, k5)
+    ASMSubroundJ( ebp, eax, ebx, ecx, edx,  8, 11, k5)
+    ASMSubroundJ( edx, ebp, eax, ebx, ecx,  1, 14, k5)
+    ASMSubroundJ( ecx, edx, ebp, eax, ebx, 10, 14, k5)
+    ASMSubroundJ( ebx, ecx, edx, ebp, eax,  3, 12, k5)
+    ASMSubroundJ( eax, ebx, ecx, edx, ebp, 12,  6, k5)
+
+    // setup
+    AS2(    mov   esi, ebx      )
+
+    ASMSubroundI( ebp, eax, ebx, ecx, edx,  6,  9, k6) 
+    ASMSubroundI( edx, ebp, eax, ebx, ecx, 11, 13, k6)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  3, 15, k6)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax,  7,  7, k6)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp,  0, 12, k6)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx, 13,  8, k6)
+    ASMSubroundI( edx, ebp, eax, ebx, ecx,  5,  9, k6)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx, 10, 11, k6)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax, 14,  7, k6)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp, 15,  7, k6)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx,  8, 12, k6)
+    ASMSubroundI( edx, ebp, eax, ebx, ecx, 12,  7, k6)
+    ASMSubroundI( ecx, edx, ebp, eax, ebx,  4,  6, k6)
+    ASMSubroundI( ebx, ecx, edx, ebp, eax,  9, 15, k6)
+    ASMSubroundI( eax, ebx, ecx, edx, ebp,  1, 13, k6)
+    ASMSubroundI( ebp, eax, ebx, ecx, edx,  2, 11, k6)
+
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 15,  9, k7)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx,  5,  7, k7)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax,  1, 15, k7)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp,  3, 11, k7)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  7,  8, k7)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 14,  6, k7)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx,  6,  6, k7)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax,  9, 14, k7)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp, 11, 12, k7)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  8, 13, k7)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 12,  5, k7)
+    ASMSubroundH( ecx, edx, ebp, eax, ebx,  2, 14, k7)
+    ASMSubroundH( ebx, ecx, edx, ebp, eax, 10, 13, k7)
+    ASMSubroundH( eax, ebx, ecx, edx, ebp,  0, 13, k7)
+    ASMSubroundH( ebp, eax, ebx, ecx, edx,  4,  7, k7)
+    ASMSubroundH( edx, ebp, eax, ebx, ecx, 13,  5, k7)
+
+    ASMSubroundG( ecx, edx, ebp, eax, ebx,  8, 15, k8)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax,  6,  5, k8)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp,  4,  8, k8)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  1, 11, k8)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx,  3, 14, k8)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx, 11, 14, k8)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax, 15,  6, k8)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp,  0, 14, k8)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  5,  6, k8)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx, 12,  9, k8)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx,  2, 12, k8)
+    ASMSubroundG( ebx, ecx, edx, ebp, eax, 13,  9, k8)
+    ASMSubroundG( eax, ebx, ecx, edx, ebp,  9, 12, k8)
+    ASMSubroundG( ebp, eax, ebx, ecx, edx,  7,  5, k8)
+    ASMSubroundG( edx, ebp, eax, ebx, ecx, 10, 15, k8)
+    ASMSubroundG( ecx, edx, ebp, eax, ebx, 14,  8, k8)
+
+    ASMSubroundF( ebx, ecx, edx, ebp, eax, 12,  8)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp, 15,  5)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx, 10, 12)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx,  4,  9)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx,  1, 12)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax,  5,  5)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp,  8, 14)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx,  7,  6)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx,  6,  8)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx,  2, 13)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax, 13,  6)
+    ASMSubroundF( eax, ebx, ecx, edx, ebp, 14,  5)
+    ASMSubroundF( ebp, eax, ebx, ecx, edx,  0, 15)
+    ASMSubroundF( edx, ebp, eax, ebx, ecx,  3, 13)
+    ASMSubroundF( ecx, edx, ebp, eax, ebx,  9, 11)
+    ASMSubroundF( ebx, ecx, edx, ebp, eax, 11, 11)
+
+    // advance data and store for next round
+    AS2(    add   edi, 64                       )
+    AS2(    movd  esi, mm1                      )   // digest_
+    AS2(    movd  mm0, edi                      )   // store
+
+    // now edi as tmp
+
+    // c1         = digest_[1] + c1 + d2;
+    AS2(    add   [esp +  8], edx               )   // + d2
+    AS2(    mov   edi, [esi + 4]                )   // digest_[1]
+    AS2(    add   [esp +  8], edi               )
+
+    // digest_[1] = digest_[2] + d1 + e2;
+    AS2(    mov   [esi + 4], ebp                )   // e2
+    AS2(    mov   edi, [esp + 12]               )   // d1
+    AS2(    add   edi, [esi + 8]                )   // digest_[2]
+    AS2(    add   [esi + 4], edi                )
+
+    // digest_[2] = digest_[3] + e1 + a2;
+    AS2(    mov   [esi + 8], eax                )   // a2
+    AS2(    mov   edi, [esp + 16]               )   // e1
+    AS2(    add   edi, [esi + 12]               )   // digest_[3]
+    AS2(    add   [esi + 8], edi                )
+
+    // digest_[3] = digest_[4] + a1 + b2;
+    AS2(    mov   [esi + 12], ebx               )   // b2
+    AS2(    mov   edi, [esp]                    )   // a1
+    AS2(    add   edi, [esi + 16]               )   // digest_[4]
+    AS2(    add   [esi + 12], edi               )
+
+    // digest_[4] = digest_[0] + b1 + c2;
+    AS2(    mov   [esi + 16], ecx               )   // c2
+    AS2(    mov   edi, [esp +  4]               )   // b1
+    AS2(    add   edi, [esi]                    )   // digest_[0]
+    AS2(    add   [esi + 16], edi               )
+
+    // digest_[0] = c1;
+    AS2(    mov   edi, [esp +  8]               )   // c1
+    AS2(    mov   [esi], edi                    )
+
+    // setup for loop back
+    AS2(    movd  edx, mm2              )   // times
+    AS2(    movd  edi, mm0              )   // data, already advanced
+    AS1(    dec   edx                   )
+    AS1(    jnz   loopStart             )
+
+
+    EPILOG()
+}
+
+
+#endif // DO_RIPEMD_ASM
+
+
 } // namespace TaoCrypt
diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp
index 13a4cfc22d3..12f80c1af75 100644
--- a/extra/yassl/taocrypt/src/sha.cpp
+++ b/extra/yassl/taocrypt/src/sha.cpp
@@ -27,6 +27,11 @@
 #include "sha.hpp"
 
 
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_SHA_ASM
+#endif
+
+
 namespace TaoCrypt {
 
 #define blk0(i) (W[i] = buffer_[i])
@@ -60,7 +65,8 @@ void SHA::Init()
     digest_[4] = 0xC3D2E1F0L;
 
     buffLen_ = 0;
-    length_  = 0;
+    loLen_  = 0;
+    hiLen_  = 0;
 }
 
 
@@ -68,7 +74,8 @@ SHA::SHA(const SHA& that) : HASHwithTransform(DIGEST_SIZE / sizeof(word32),
                                               BLOCK_SIZE) 
 { 
     buffLen_ = that.buffLen_;
-    length_  = that.length_;
+    loLen_   = that.loLen_;
+    hiLen_   = that.hiLen_;
 
     memcpy(digest_, that.digest_, DIGEST_SIZE);
     memcpy(buffer_, that.buffer_, BLOCK_SIZE);
@@ -85,7 +92,8 @@ SHA& SHA::operator= (const SHA& that)
 
 void SHA::Swap(SHA& other)
 {
-    mySTL::swap(length_,  other.length_);
+    mySTL::swap(loLen_,   other.loLen_);
+    mySTL::swap(hiLen_,   other.hiLen_);
     mySTL::swap(buffLen_, other.buffLen_);
 
     memcpy(digest_, other.digest_, DIGEST_SIZE);
@@ -93,6 +101,61 @@ void SHA::Swap(SHA& other)
 }
 
 
+// Update digest with data of size len, do in blocks
+void SHA::Update(const byte* data, word32 len)
+{
+    byte* local = (byte*)buffer_;
+
+    // remove buffered data if possible
+    if (buffLen_)  {   
+        word32 add = min(len, BLOCK_SIZE - buffLen_);
+        memcpy(&local[buffLen_], data, add);
+
+        buffLen_ += add;
+        data     += add;
+        len      -= add;
+
+        if (buffLen_ == BLOCK_SIZE) {
+            ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder);
+            Transform();
+            AddLength(BLOCK_SIZE);
+            buffLen_ = 0;
+        }
+    }
+
+    // do block size transforms or all at once for asm
+    if (buffLen_ == 0) {
+        #ifndef DO_SHA_ASM
+            while (len >= BLOCK_SIZE) {
+                memcpy(&local[0], data, BLOCK_SIZE);
+
+                data     += BLOCK_SIZE;
+                len      -= BLOCK_SIZE;
+
+                ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder);
+                Transform();
+                AddLength(BLOCK_SIZE);
+            }
+        #else
+            word32 times = len / BLOCK_SIZE;
+            if (times) {
+                AsmTransform(data, times);
+                const word32 add = BLOCK_SIZE * times;
+                AddLength(add);
+                 len  -= add;
+                data += add;
+            }
+        #endif
+    }
+
+    // cache any data left
+    if (len) {
+        memcpy(&local[buffLen_], data, len);
+        buffLen_ += len;
+    }
+}
+
+
 void SHA::Transform()
 {
     word32 W[BLOCK_SIZE / sizeof(word32)];
@@ -109,17 +172,21 @@ void SHA::Transform()
     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+
     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+
     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+
     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+
     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
@@ -136,10 +203,414 @@ void SHA::Transform()
     // Wipe variables
     a = b = c = d = e = 0;
     memset(W, 0, sizeof(W));
-
-    buffLen_ = 0;
-    length_ += 512;
 }
 
 
+#ifdef DO_SHA_ASM
+
+// f1(x,y,z) (z^(x &(y^z)))
+// place in esi
+#define ASMf1(x,y,z)   \
+    AS2(    mov   esi, y    )   \
+    AS2(    xor   esi, z    )   \
+    AS2(    and   esi, x    )   \
+    AS2(    xor   esi, z    )
+
+
+// R0(v,w,x,y,z,i) =
+//      z+= f1(w,x,y) + W[i] + 0x5A827999 + rotlFixed(v,5);
+//      w = rotlFixed(w,30);
+
+//      use esi for f
+//      use edi as tmp
+
+
+#define ASMR0(v,w,x,y,z,i) \
+    AS2(    mov   esi, x                        )   \
+    AS2(    mov   edi, [esp + i * 4]            )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    and   esi, w                        )   \
+    AS2(    lea     z, [edi + z + 0x5A827999]   )   \
+    AS2(    mov   edi, v                        )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    rol   edi, 5                        )   \
+    AS2(    add     z, esi                      )   \
+    AS2(    rol     w, 30                       )   \
+    AS2(    add     z, edi                      )
+
+
+/*  Some macro stuff, but older gas ( < 2,16 ) can't process &, so do by hand
+    % won't work on gas at all
+
+#define xstr(s) str(s)
+#define  str(s) #s
+
+#define WOFF1(a) ( a       & 15)
+#define WOFF2(a) ((a +  2) & 15)
+#define WOFF3(a) ((a +  8) & 15)
+#define WOFF4(a) ((a + 13) & 15)
+
+#ifdef __GNUC__
+    #define WGET1(i) asm("mov esp, [edi - "xstr(WOFF1(i))" * 4] ");
+    #define WGET2(i) asm("xor esp, [edi - "xstr(WOFF2(i))" * 4] ");
+    #define WGET3(i) asm("xor esp, [edi - "xstr(WOFF3(i))" * 4] ");
+    #define WGET4(i) asm("xor esp, [edi - "xstr(WOFF4(i))" * 4] ");
+    #define WPUT1(i) asm("mov [edi - "xstr(WOFF1(i))" * 4], esp ");
+#else
+    #define WGET1(i) AS2( mov   esp, [edi - WOFF1(i) * 4]   )
+    #define WGET2(i) AS2( xor   esp, [edi - WOFF2(i) * 4]   )
+    #define WGET3(i) AS2( xor   esp, [edi - WOFF3(i) * 4]   )
+    #define WGET4(i) AS2( xor   esp, [edi - WOFF4(i) * 4]   )
+    #define WPUT1(i) AS2( mov   [edi - WOFF1(i) * 4], esp   )
+#endif
+*/
+
+// ASMR1 = ASMR0 but use esp for W calcs
+
+#define ASMR1(v,w,x,y,z,i,W1,W2,W3,W4) \
+    AS2(    mov   edi, [esp + W1 * 4]           )   \
+    AS2(    mov   esi, x                        )   \
+    AS2(    xor   edi, [esp + W2 * 4]           )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    xor   edi, [esp + W3 * 4]           )   \
+    AS2(    and   esi, w                        )   \
+    AS2(    xor   edi, [esp + W4 * 4]           )   \
+    AS2(    rol   edi, 1                        )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    mov   [esp + W1 * 4], edi           )   \
+    AS2(    lea     z, [edi + z + 0x5A827999]   )   \
+    AS2(    mov   edi, v                        )   \
+    AS2(    rol   edi, 5                        )   \
+    AS2(    add     z, esi                      )   \
+    AS2(    rol     w, 30                       )   \
+    AS2(    add     z, edi                      )
+
+
+// ASMR2 = ASMR1 but f is xor, xor instead
+
+#define ASMR2(v,w,x,y,z,i,W1,W2,W3,W4) \
+    AS2(    mov   edi, [esp + W1 * 4]           )   \
+    AS2(    mov   esi, x                        )   \
+    AS2(    xor   edi, [esp + W2 * 4]           )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    xor   edi, [esp + W3 * 4]           )   \
+    AS2(    xor   esi, w                        )   \
+    AS2(    xor   edi, [esp + W4 * 4]           )   \
+    AS2(    rol   edi, 1                        )   \
+    AS2(    add     z, esi                      )   \
+    AS2(    mov   [esp + W1 * 4], edi           )   \
+    AS2(    lea     z, [edi + z + 0x6ED9EBA1]   )   \
+    AS2(    mov   edi, v                        )   \
+    AS2(    rol   edi, 5                        )   \
+    AS2(    rol     w, 30                       )   \
+    AS2(    add     z, edi                      )
+
+
+// ASMR3 = ASMR2 but f is (x&y)|(z&(x|y))
+//               which is (w&x)|(y&(w|x))
+
+#define ASMR3(v,w,x,y,z,i,W1,W2,W3,W4) \
+    AS2(    mov   edi, [esp + W1 * 4]           )   \
+    AS2(    mov   esi, x                        )   \
+    AS2(    xor   edi, [esp + W2 * 4]           )   \
+    AS2(     or   esi, w                        )   \
+    AS2(    xor   edi, [esp + W3 * 4]           )   \
+    AS2(    and   esi, y                        )   \
+    AS2(    xor   edi, [esp + W4 * 4]           )   \
+    AS2(    movd  mm0, esi                      )   \
+    AS2(    rol   edi, 1                        )   \
+    AS2(    mov   esi, x                        )   \
+    AS2(    mov   [esp + W1 * 4], edi           )   \
+    AS2(    and   esi, w                        )   \
+    AS2(    lea     z, [edi + z + 0x8F1BBCDC]   )   \
+    AS2(    movd  edi, mm0                      )   \
+    AS2(     or   esi, edi                      )   \
+    AS2(    mov   edi, v                        )   \
+    AS2(    rol   edi, 5                        )   \
+    AS2(    add     z, esi                      )   \
+    AS2(    rol     w, 30                       )   \
+    AS2(    add     z, edi                      )
+
+
+// ASMR4 = ASMR2 but different constant
+
+#define ASMR4(v,w,x,y,z,i,W1,W2,W3,W4) \
+    AS2(    mov   edi, [esp + W1 * 4]           )   \
+    AS2(    mov   esi, x                        )   \
+    AS2(    xor   edi, [esp + W2 * 4]           )   \
+    AS2(    xor   esi, y                        )   \
+    AS2(    xor   edi, [esp + W3 * 4]           )   \
+    AS2(    xor   esi, w                        )   \
+    AS2(    xor   edi, [esp + W4 * 4]           )   \
+    AS2(    rol   edi, 1                        )   \
+    AS2(    add     z, esi                      )   \
+    AS2(    mov   [esp + W1 * 4], edi           )   \
+    AS2(    lea     z, [edi + z + 0xCA62C1D6]   )   \
+    AS2(    mov   edi, v                        )   \
+    AS2(    rol   edi, 5                        )   \
+    AS2(    rol     w, 30                       )   \
+    AS2(    add     z, edi                      )
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void SHA::AsmTransform(const byte* data, word32 times)
+{
+#ifdef __GNUC__
+    #define AS1(x)    asm(#x);
+    #define AS2(x, y) asm(#x ", " #y);
+
+    #define PROLOG()  \
+        asm(".intel_syntax noprefix"); \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   ecx, DWORD PTR [ebp +  8]     )   \
+        AS2(    mov   edi, DWORD PTR [ebp + 12]     )   \
+        AS2(    mov   eax, DWORD PTR [ebp + 16]     )
+
+    #define EPILOG()  \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS1(    emms                            )   \
+        asm(".att_syntax");
+#else
+    #define AS1(x)    __asm x
+    #define AS2(x, y) __asm x, y
+
+    #define PROLOG() \
+        AS1(    push  ebp                           )   \
+        AS2(    mov   ebp, esp                      )   \
+        AS2(    movd  mm3, edi                      )   \
+        AS2(    movd  mm4, ebx                      )   \
+        AS2(    movd  mm5, esi                      )   \
+        AS2(    movd  mm6, ebp                      )   \
+        AS2(    mov   edi, data                     )   \
+        AS2(    mov   eax, times                    )
+
+    #define EPILOG() \
+        AS2(    movd  ebp, mm6                  )   \
+        AS2(    movd  esi, mm5                  )   \
+        AS2(    movd  ebx, mm4                  )   \
+        AS2(    movd  edi, mm3                  )   \
+        AS2(    mov   esp, ebp                  )   \
+        AS1(    pop   ebp                       )   \
+        AS1(    emms   )                            \
+        AS1(    ret 8  )   
+#endif
+
+    PROLOG()
+
+    AS2(    mov   esi, ecx              )
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    add   esi, 20               )   // digest_[0]
+    #else
+        AS2(    add   esi, 16               )   // digest_[0]
+    #endif
+
+    AS2(    movd  mm2, eax              )   // store times_
+    AS2(    movd  mm1, esi              )   // store digest_
+
+    AS2(    sub   esp, 68               )   // make room on stack
+
+AS1( loopStart: )
+
+    // byte reverse 16 words of input, 4 at a time, put on stack for W[]
+
+    // part 1
+    AS2(    mov   eax, [edi]        )
+    AS2(    mov   ebx, [edi +  4]   )
+    AS2(    mov   ecx, [edi +  8]   )
+    AS2(    mov   edx, [edi + 12]   )
+
+    AS1(    bswap eax   )
+    AS1(    bswap ebx   )
+    AS1(    bswap ecx   )
+    AS1(    bswap edx   )
+
+    AS2(    mov   [esp],      eax   )
+    AS2(    mov   [esp +  4], ebx   )
+    AS2(    mov   [esp +  8], ecx   )
+    AS2(    mov   [esp + 12], edx   )
+
+    // part 2
+    AS2(    mov   eax, [edi + 16]   )
+    AS2(    mov   ebx, [edi + 20]   )
+    AS2(    mov   ecx, [edi + 24]   )
+    AS2(    mov   edx, [edi + 28]   )
+
+    AS1(    bswap eax   )
+    AS1(    bswap ebx   )
+    AS1(    bswap ecx   )
+    AS1(    bswap edx   )
+
+    AS2(    mov   [esp + 16], eax   )
+    AS2(    mov   [esp + 20], ebx   )
+    AS2(    mov   [esp + 24], ecx   )
+    AS2(    mov   [esp + 28], edx   )
+
+
+    // part 3
+    AS2(    mov   eax, [edi + 32]   )
+    AS2(    mov   ebx, [edi + 36]   )
+    AS2(    mov   ecx, [edi + 40]   )
+    AS2(    mov   edx, [edi + 44]   )
+
+    AS1(    bswap eax   )
+    AS1(    bswap ebx   )
+    AS1(    bswap ecx   )
+    AS1(    bswap edx   )
+
+    AS2(    mov   [esp + 32], eax   )
+    AS2(    mov   [esp + 36], ebx   )
+    AS2(    mov   [esp + 40], ecx   )
+    AS2(    mov   [esp + 44], edx   )
+
+
+    // part 4
+    AS2(    mov   eax, [edi + 48]   )
+    AS2(    mov   ebx, [edi + 52]   )
+    AS2(    mov   ecx, [edi + 56]   )
+    AS2(    mov   edx, [edi + 60]   )
+
+    AS1(    bswap eax   )
+    AS1(    bswap ebx   )
+    AS1(    bswap ecx   )
+    AS1(    bswap edx   )
+
+    AS2(    mov   [esp + 48], eax   )
+    AS2(    mov   [esp + 52], ebx   )
+    AS2(    mov   [esp + 56], ecx   )
+    AS2(    mov   [esp + 60], edx   )
+
+    AS2(    mov   [esp + 64], edi   )   // store edi for end
+
+    // read from digest_
+    AS2(    mov   eax, [esi]            )   // a1
+    AS2(    mov   ebx, [esi +  4]       )   // b1
+    AS2(    mov   ecx, [esi +  8]       )   // c1
+    AS2(    mov   edx, [esi + 12]       )   // d1
+    AS2(    mov   ebp, [esi + 16]       )   // e1
+
+
+    ASMR0(eax, ebx, ecx, edx, ebp,  0)
+    ASMR0(ebp, eax, ebx, ecx, edx,  1)
+    ASMR0(edx, ebp, eax, ebx, ecx,  2)
+    ASMR0(ecx, edx, ebp, eax, ebx,  3)
+    ASMR0(ebx, ecx, edx, ebp, eax,  4)
+    ASMR0(eax, ebx, ecx, edx, ebp,  5)
+    ASMR0(ebp, eax, ebx, ecx, edx,  6)
+    ASMR0(edx, ebp, eax, ebx, ecx,  7)
+    ASMR0(ecx, edx, ebp, eax, ebx,  8)
+    ASMR0(ebx, ecx, edx, ebp, eax,  9)
+    ASMR0(eax, ebx, ecx, edx, ebp, 10)
+    ASMR0(ebp, eax, ebx, ecx, edx, 11)
+    ASMR0(edx, ebp, eax, ebx, ecx, 12)
+    ASMR0(ecx, edx, ebp, eax, ebx, 13)
+    ASMR0(ebx, ecx, edx, ebp, eax, 14)
+    ASMR0(eax, ebx, ecx, edx, ebp, 15)
+
+    ASMR1(ebp, eax, ebx, ecx, edx, 16,  0,  2,  8, 13)
+    ASMR1(edx, ebp, eax, ebx, ecx, 17,  1,  3,  9, 14)
+    ASMR1(ecx, edx, ebp, eax, ebx, 18,  2,  4, 10, 15)
+    ASMR1(ebx, ecx, edx, ebp, eax, 19,  3,  5, 11,  0)
+
+    ASMR2(eax, ebx, ecx, edx, ebp, 20,  4,  6, 12,  1)
+    ASMR2(ebp, eax, ebx, ecx, edx, 21,  5,  7, 13,  2)
+    ASMR2(edx, ebp, eax, ebx, ecx, 22,  6,  8, 14,  3)
+    ASMR2(ecx, edx, ebp, eax, ebx, 23,  7,  9, 15,  4)
+    ASMR2(ebx, ecx, edx, ebp, eax, 24,  8, 10,  0,  5)
+    ASMR2(eax, ebx, ecx, edx, ebp, 25,  9, 11,  1,  6)
+    ASMR2(ebp, eax, ebx, ecx, edx, 26, 10, 12,  2,  7)
+    ASMR2(edx, ebp, eax, ebx, ecx, 27, 11, 13,  3,  8)
+    ASMR2(ecx, edx, ebp, eax, ebx, 28, 12, 14,  4,  9)
+    ASMR2(ebx, ecx, edx, ebp, eax, 29, 13, 15,  5, 10)
+    ASMR2(eax, ebx, ecx, edx, ebp, 30, 14,  0,  6, 11)
+    ASMR2(ebp, eax, ebx, ecx, edx, 31, 15,  1,  7, 12)
+    ASMR2(edx, ebp, eax, ebx, ecx, 32,  0,  2,  8, 13)
+    ASMR2(ecx, edx, ebp, eax, ebx, 33,  1,  3,  9, 14)
+    ASMR2(ebx, ecx, edx, ebp, eax, 34,  2,  4, 10, 15)
+    ASMR2(eax, ebx, ecx, edx, ebp, 35,  3,  5, 11,  0)
+    ASMR2(ebp, eax, ebx, ecx, edx, 36,  4,  6, 12,  1)
+    ASMR2(edx, ebp, eax, ebx, ecx, 37,  5,  7, 13,  2)
+    ASMR2(ecx, edx, ebp, eax, ebx, 38,  6,  8, 14,  3)
+    ASMR2(ebx, ecx, edx, ebp, eax, 39,  7,  9, 15,  4)
+
+
+    ASMR3(eax, ebx, ecx, edx, ebp, 40,  8, 10,  0,  5)
+    ASMR3(ebp, eax, ebx, ecx, edx, 41,  9, 11,  1,  6)
+    ASMR3(edx, ebp, eax, ebx, ecx, 42, 10, 12,  2,  7)
+    ASMR3(ecx, edx, ebp, eax, ebx, 43, 11, 13,  3,  8)
+    ASMR3(ebx, ecx, edx, ebp, eax, 44, 12, 14,  4,  9)
+    ASMR3(eax, ebx, ecx, edx, ebp, 45, 13, 15,  5, 10)
+    ASMR3(ebp, eax, ebx, ecx, edx, 46, 14,  0,  6, 11)
+    ASMR3(edx, ebp, eax, ebx, ecx, 47, 15,  1,  7, 12)
+    ASMR3(ecx, edx, ebp, eax, ebx, 48,  0,  2,  8, 13)
+    ASMR3(ebx, ecx, edx, ebp, eax, 49,  1,  3,  9, 14)
+    ASMR3(eax, ebx, ecx, edx, ebp, 50,  2,  4, 10, 15)
+    ASMR3(ebp, eax, ebx, ecx, edx, 51,  3,  5, 11,  0)
+    ASMR3(edx, ebp, eax, ebx, ecx, 52,  4,  6, 12,  1)
+    ASMR3(ecx, edx, ebp, eax, ebx, 53,  5,  7, 13,  2)
+    ASMR3(ebx, ecx, edx, ebp, eax, 54,  6,  8, 14,  3)
+    ASMR3(eax, ebx, ecx, edx, ebp, 55,  7,  9, 15,  4)
+    ASMR3(ebp, eax, ebx, ecx, edx, 56,  8, 10,  0,  5)
+    ASMR3(edx, ebp, eax, ebx, ecx, 57,  9, 11,  1,  6)
+    ASMR3(ecx, edx, ebp, eax, ebx, 58, 10, 12,  2,  7)
+    ASMR3(ebx, ecx, edx, ebp, eax, 59, 11, 13,  3,  8)
+
+    ASMR4(eax, ebx, ecx, edx, ebp, 60, 12, 14,  4,  9)
+    ASMR4(ebp, eax, ebx, ecx, edx, 61, 13, 15,  5, 10)
+    ASMR4(edx, ebp, eax, ebx, ecx, 62, 14,  0,  6, 11)
+    ASMR4(ecx, edx, ebp, eax, ebx, 63, 15,  1,  7, 12)
+    ASMR4(ebx, ecx, edx, ebp, eax, 64,  0,  2,  8, 13)
+    ASMR4(eax, ebx, ecx, edx, ebp, 65,  1,  3,  9, 14)
+    ASMR4(ebp, eax, ebx, ecx, edx, 66,  2,  4, 10, 15)
+    ASMR4(edx, ebp, eax, ebx, ecx, 67,  3,  5, 11,  0)
+    ASMR4(ecx, edx, ebp, eax, ebx, 68,  4,  6, 12,  1)
+    ASMR4(ebx, ecx, edx, ebp, eax, 69,  5,  7, 13,  2)
+    ASMR4(eax, ebx, ecx, edx, ebp, 70,  6,  8, 14,  3)
+    ASMR4(ebp, eax, ebx, ecx, edx, 71,  7,  9, 15,  4)
+    ASMR4(edx, ebp, eax, ebx, ecx, 72,  8, 10,  0,  5)
+    ASMR4(ecx, edx, ebp, eax, ebx, 73,  9, 11,  1,  6)
+    ASMR4(ebx, ecx, edx, ebp, eax, 74, 10, 12,  2,  7)
+    ASMR4(eax, ebx, ecx, edx, ebp, 75, 11, 13,  3,  8)
+    ASMR4(ebp, eax, ebx, ecx, edx, 76, 12, 14,  4,  9)
+    ASMR4(edx, ebp, eax, ebx, ecx, 77, 13, 15,  5, 10)
+    ASMR4(ecx, edx, ebp, eax, ebx, 78, 14,  0,  6, 11)
+    ASMR4(ebx, ecx, edx, ebp, eax, 79, 15,  1,  7, 12)
+
+
+    AS2(    movd  esi, mm1              )   // digest_
+
+    AS2(    add   [esi],      eax       )   // write out
+    AS2(    add   [esi +  4], ebx       )
+    AS2(    add   [esi +  8], ecx       )
+    AS2(    add   [esi + 12], edx       )
+    AS2(    add   [esi + 16], ebp       )
+
+    // setup next round
+    AS2(    movd  ebp, mm2              )   // times
+ 
+    AS2(    mov   edi, DWORD PTR [esp + 64] )   // data
+    
+    AS2(    add   edi, 64               )   // next round of data
+    AS2(    mov   [esp + 64], edi       )   // restore
+    
+    AS1(    dec   ebp                   )
+    AS2(    movd  mm2, ebp              )
+    AS1(    jnz   loopStart             )
+
+
+    EPILOG()
+}
+
+
+#endif // DO_SHA_ASM
+
 } // namespace
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 59814d03209..12bcd8238f2 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -24,8 +24,14 @@
  */
 
 
+#include "runtime.hpp"
 #include "integer.hpp"
 #include "rsa.hpp"
+#include "sha.hpp"
+#include "md5.hpp"
+#include "hmac.hpp"
+#include "ripemd.hpp"
+#include "pwdbased.hpp"
 #include "algebra.hpp"
 #include "vector.hpp"
 #include "hash.hpp"
@@ -53,6 +59,12 @@ template AllocatorWithCleanup::pointer StdReallocate(char*);
+
+template class PBKDF2_HMAC;
+template class HMAC;
+template class HMAC;
+template class HMAC;
+
 }
 
 namespace mySTL {
diff --git a/extra/yassl/taocrypt/src/tftables.cpp b/extra/yassl/taocrypt/src/tftables.cpp
new file mode 100644
index 00000000000..55846d5f79d
--- /dev/null
+++ b/extra/yassl/taocrypt/src/tftables.cpp
@@ -0,0 +1,352 @@
+/* tftables.cpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* based on Wei Dai's tftables.cpp from CryptoPP */
+
+#include "runtime.hpp"
+#include "twofish.hpp"
+
+
+namespace TaoCrypt {
+
+
+const byte Twofish::q_[2][256] = {
+{
+   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+   0x4A, 0x5E, 0xC1, 0xE0
+},
+{
+   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+   0x55, 0x09, 0xBE, 0x91
+}
+};
+
+
+const word32 Twofish::mds_[4][256] = {
+    {
+	0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, 
+	0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, 
+	0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, 
+	0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, 
+	0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, 
+	0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, 
+	0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, 
+	0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, 
+	0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, 
+	0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, 
+	0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, 
+	0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, 
+	0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, 
+	0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, 
+	0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, 
+	0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, 
+	0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, 
+	0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, 
+	0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, 
+	0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, 
+	0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, 
+	0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, 
+	0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, 
+	0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, 
+	0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, 
+	0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, 
+	0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, 
+	0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, 
+	0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, 
+	0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, 
+	0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, 
+	0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, 
+	0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, 
+	0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, 
+	0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, 
+	0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, 
+	0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, 
+	0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, 
+	0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, 
+	0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, 
+	0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, 
+	0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, 
+	0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, 
+	0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, 
+	0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, 
+	0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, 
+	0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, 
+	0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, 
+	0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, 
+	0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, 
+	0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, 
+	0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, 
+	0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, 
+	0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, 
+	0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, 
+	0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, 
+	0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, 
+	0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, 
+	0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, 
+	0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, 
+	0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, 
+	0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, 
+	0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, 
+	0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91
+    },
+    {
+	0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, 
+	0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, 
+	0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, 
+	0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, 
+	0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, 
+	0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, 
+	0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, 
+	0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, 
+	0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, 
+	0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, 
+	0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, 
+	0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, 
+	0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, 
+	0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, 
+	0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, 
+	0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, 
+	0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, 
+	0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, 
+	0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, 
+	0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, 
+	0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, 
+	0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, 
+	0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, 
+	0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, 
+	0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, 
+	0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, 
+	0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, 
+	0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, 
+	0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, 
+	0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, 
+	0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, 
+	0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, 
+	0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, 
+	0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, 
+	0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, 
+	0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, 
+	0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, 
+	0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, 
+	0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, 
+	0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, 
+	0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, 
+	0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, 
+	0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, 
+	0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, 
+	0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, 
+	0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, 
+	0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, 
+	0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, 
+	0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, 
+	0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, 
+	0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, 
+	0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, 
+	0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, 
+	0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, 
+	0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, 
+	0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, 
+	0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, 
+	0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, 
+	0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, 
+	0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, 
+	0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, 
+	0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, 
+	0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, 
+	0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8
+    },
+    {
+	0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, 
+	0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, 
+	0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, 
+	0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, 
+	0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, 
+	0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, 
+	0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, 
+	0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, 
+	0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, 
+	0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, 
+	0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, 
+	0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, 
+	0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, 
+	0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, 
+	0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, 
+	0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, 
+	0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, 
+	0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, 
+	0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, 
+	0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, 
+	0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, 
+	0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, 
+	0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, 
+	0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, 
+	0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, 
+	0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, 
+	0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, 
+	0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, 
+	0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, 
+	0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, 
+	0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, 
+	0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, 
+	0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, 
+	0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, 
+	0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, 
+	0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, 
+	0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, 
+	0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, 
+	0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, 
+	0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, 
+	0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, 
+	0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, 
+	0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, 
+	0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, 
+	0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, 
+	0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, 
+	0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, 
+	0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, 
+	0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, 
+	0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, 
+	0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, 
+	0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, 
+	0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, 
+	0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, 
+	0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, 
+	0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, 
+	0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, 
+	0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, 
+	0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, 
+	0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, 
+	0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, 
+	0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, 
+	0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, 
+	0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef
+    },
+    {
+	0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, 
+	0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, 
+	0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, 
+	0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, 
+	0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, 
+	0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, 
+	0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, 
+	0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, 
+	0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, 
+	0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, 
+	0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, 
+	0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, 
+	0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, 
+	0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, 
+	0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, 
+	0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, 
+	0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, 
+	0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, 
+	0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, 
+	0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, 
+	0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, 
+	0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, 
+	0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, 
+	0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, 
+	0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, 
+	0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, 
+	0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, 
+	0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, 
+	0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, 
+	0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, 
+	0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, 
+	0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, 
+	0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, 
+	0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, 
+	0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, 
+	0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, 
+	0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, 
+	0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, 
+	0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, 
+	0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, 
+	0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, 
+	0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, 
+	0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, 
+	0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, 
+	0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, 
+	0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, 
+	0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, 
+	0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, 
+	0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, 
+	0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, 
+	0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, 
+	0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, 
+	0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, 
+	0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, 
+	0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, 
+	0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, 
+	0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, 
+	0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, 
+	0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, 
+	0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, 
+	0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, 
+	0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, 
+	0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, 
+	0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8
+    }
+};
+
+
+} // namespace
+
diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp
new file mode 100644
index 00000000000..8b896ad5dc4
--- /dev/null
+++ b/extra/yassl/taocrypt/src/twofish.cpp
@@ -0,0 +1,591 @@
+/* twofish.cpp                                
+ *
+ * Copyright (C) 2003 Sawtooth Consulting Ltd.
+ *
+ * This file is part of yaSSL.
+ *
+ * yaSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * yaSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* C++ based on Wei Dai's twofish.cpp from CryptoPP */
+/* x86 asm original */
+
+
+#if defined(TAOCRYPT_KERNEL_MODE)
+    #define DO_TAOCRYPT_KERNEL_MODE
+#endif                                  // only some modules now support this
+
+#include "runtime.hpp"
+#include "twofish.hpp"
+
+
+#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM)
+    #define DO_TWOFISH_ASM
+#endif
+
+
+namespace TaoCrypt {
+
+
+#if !defined(DO_TWOFISH_ASM)
+
+// Generic Version
+void Twofish::Process(byte* out, const byte* in, word32 sz)
+{
+    if (mode_ == ECB)
+        ECB_Process(out, in, sz);
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            CBC_Encrypt(out, in, sz);
+        else
+            CBC_Decrypt(out, in, sz);
+}
+
+#else
+
+// ia32 optimized version
+void Twofish::Process(byte* out, const byte* in, word32 sz)
+{
+    word32 blocks = sz / BLOCK_SIZE;
+
+    if (mode_ == ECB)
+        while (blocks--) {
+            if (dir_ == ENCRYPTION)
+                AsmEncrypt(in, out);
+            else
+                AsmDecrypt(in, out);
+        
+            out += BLOCK_SIZE;
+            in  += BLOCK_SIZE;
+        }
+    else if (mode_ == CBC)
+        if (dir_ == ENCRYPTION)
+            while (blocks--) {
+                r_[0] ^= *(word32*)in;
+                r_[1] ^= *(word32*)(in +  4);
+                r_[2] ^= *(word32*)(in +  8);
+                r_[3] ^= *(word32*)(in + 12);
+
+                AsmEncrypt((byte*)r_, (byte*)r_);
+                memcpy(out, r_, BLOCK_SIZE);
+
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+        else
+            while (blocks--) {
+                AsmDecrypt(in, out);
+               
+                *(word32*)out        ^= r_[0];
+                *(word32*)(out +  4) ^= r_[1];
+                *(word32*)(out +  8) ^= r_[2];
+                *(word32*)(out + 12) ^= r_[3];
+
+                memcpy(r_, in, BLOCK_SIZE);
+
+                out += BLOCK_SIZE;
+                in  += BLOCK_SIZE;
+            }
+}
+
+#endif // DO_TWOFISH_ASM
+
+
+namespace {     // locals
+
+// compute (c * x^4) mod (x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1)
+// over GF(256)
+static inline unsigned int Mod(unsigned int c)
+{
+	static const unsigned int modulus = 0x14d;
+	unsigned int c2 = (c<<1) ^ ((c & 0x80) ? modulus : 0);
+	unsigned int c1 = c2 ^ (c>>1) ^ ((c & 1) ? (modulus>>1) : 0);
+	return c | (c1 << 8) | (c2 << 16) | (c1 << 24);
+}
+
+// compute RS(12,8) code with the above polynomial as generator
+// this is equivalent to multiplying by the RS matrix
+static word32 ReedSolomon(word32 high, word32 low)
+{
+	for (unsigned int i=0; i<8; i++) {
+		high = Mod(high>>24) ^ (high<<8) ^ (low>>24);
+		low <<= 8;
+	}
+	return high;
+}
+
+}  // local namespace
+
+
+
+inline word32 Twofish::h0(word32 x, const word32* key, unsigned int kLen)
+{
+	x = x | (x<<8) | (x<<16) | (x<<24);
+	switch(kLen)
+	{
+#define Q(a, b, c, d, t) q_[a][GETBYTE(t,0)] ^ (q_[b][GETBYTE(t,1)] << 8) ^  \
+            (q_[c][GETBYTE(t,2)] << 16) ^ (q_[d][GETBYTE(t,3)] << 24)
+	case 4: x = Q(1, 0, 0, 1, x) ^ key[6];
+	case 3: x = Q(1, 1, 0, 0, x) ^ key[4];
+	case 2: x = Q(0, 1, 0, 1, x) ^ key[2];
+			x = Q(0, 0, 1, 1, x) ^ key[0];
+	}
+	return x;
+}
+
+inline word32 Twofish::h(word32 x, const word32* key, unsigned int kLen)
+{
+	x = h0(x, key, kLen);
+	return mds_[0][GETBYTE(x,0)] ^ mds_[1][GETBYTE(x,1)] ^ 
+        mds_[2][GETBYTE(x,2)] ^ mds_[3][GETBYTE(x,3)];
+}
+
+
+void Twofish::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/)
+{
+	assert(keylen >= 16 && keylen <= 32);
+
+	unsigned int len = (keylen <= 16 ? 2 : (keylen <= 24 ? 3 : 4));
+    word32 key[8];
+	GetUserKey(LittleEndianOrder, key, len*2, userKey, keylen);
+
+	unsigned int i;
+	for (i=0; i<40; i+=2) {
+		word32 a = h(i, key, len);
+		word32 b = rotlFixed(h(i+1, key+1, len), 8);
+		k_[i] = a+b;
+		k_[i+1] = rotlFixed(a+2*b, 9);
+	}
+
+	word32 svec[8];
+	for (i=0; i gpBlock;
+
+void Twofish::encrypt(const byte* inBlock, const byte* xorBlock,
+                  byte* outBlock) const
+{
+	word32 x, y, a, b, c, d;
+
+	gpBlock::Get(inBlock)(a)(b)(c)(d);
+
+	a ^= k_[0];
+	b ^= k_[1];
+	c ^= k_[2];
+	d ^= k_[3];
+
+	const word32 *k = k_+8;
+
+	ENCCYCLE (0);
+	ENCCYCLE (1);
+	ENCCYCLE (2);
+	ENCCYCLE (3);
+	ENCCYCLE (4);
+	ENCCYCLE (5);
+	ENCCYCLE (6);
+	ENCCYCLE (7);
+
+	c ^= k_[4];
+	d ^= k_[5];
+	a ^= k_[6];
+	b ^= k_[7]; 
+
+	gpBlock::Put(xorBlock, outBlock)(c)(d)(a)(b);
+}
+
+
+void Twofish::decrypt(const byte* inBlock, const byte* xorBlock,
+                  byte* outBlock) const
+{
+	word32 x, y, a, b, c, d;
+
+	gpBlock::Get(inBlock)(c)(d)(a)(b);
+
+	c ^= k_[4];
+	d ^= k_[5];
+	a ^= k_[6];
+	b ^= k_[7];
+
+	const word32 *k = k_+8;
+	DECCYCLE (7);
+	DECCYCLE (6);
+	DECCYCLE (5);
+	DECCYCLE (4);
+	DECCYCLE (3);
+	DECCYCLE (2);
+	DECCYCLE (1);
+	DECCYCLE (0);
+
+	a ^= k_[0];
+	b ^= k_[1];
+	c ^= k_[2];
+	d ^= k_[3];
+
+	gpBlock::Put(xorBlock, outBlock)(a)(b)(c)(d);
+}
+
+
+
+#if defined(DO_TWOFISH_ASM)
+    #ifdef __GNUC__
+        #define AS1(x)    asm(#x);
+        #define AS2(x, y) asm(#x ", " #y);
+
+        #define PROLOG()  \
+            asm(".intel_syntax noprefix"); \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    movd  mm5, esi                      )   \
+            AS2(    movd  mm6, ebp                      )   \
+            AS2(    mov   edi, DWORD PTR [ebp +  8]     )   \
+            AS2(    mov   esi, DWORD PTR [ebp + 12]     )
+
+        #define EPILOG()  \
+            AS2(    movd esp, mm6                  )   \
+            AS2(    movd esi, mm5                  )   \
+            AS2(    movd ebx, mm4                  )   \
+            AS2(    movd edi, mm3                  )   \
+            AS1(    emms                           )   \
+            asm(".att_syntax");
+    #else
+        #define AS1(x)    __asm x
+        #define AS2(x, y) __asm x, y
+
+        #define PROLOG() \
+            AS1(    push  ebp                           )   \
+            AS2(    mov   ebp, esp                      )   \
+            AS2(    movd  mm3, edi                      )   \
+            AS2(    movd  mm4, ebx                      )   \
+            AS2(    movd  mm5, esi                      )   \
+            AS2(    movd  mm6, ebp                      )   \
+            AS2(    mov   edi, ecx                      )   \
+            AS2(    mov   esi, DWORD PTR [ebp +  8]     )
+
+        /* ebp already set */
+        #define EPILOG()  \
+            AS2(    movd esi, mm5                   )   \
+            AS2(    movd ebx, mm4                   )   \
+            AS2(    movd edi, mm3                   )   \
+            AS2(    mov  esp, ebp                   )   \
+            AS1(    pop  ebp                        )   \
+            AS1(    emms                            )   \
+            AS1(    ret 8                           )    
+            
+    #endif
+
+
+
+
+    // x = esi, y = [esp], s_ = ebp
+    // edi always open for G1 and G2
+    // G1 also uses edx after save and restore
+    // G2 also uses eax after save and restore
+    //      and ecx for tmp [esp] which Rounds also use
+    //      and restore from mm7
+
+    // x = G1(a)   bytes(0,1,2,3)
+#define ASMG1(z, zl, zh) \
+    AS2(    movd  mm2, edx                          )   \
+    AS2(    movzx edi, zl                           )   \
+    AS2(    mov   esi, DWORD PTR     [ebp + edi*4]  )   \
+    AS2(    movzx edx, zh                           )   \
+    AS2(    xor   esi, DWORD PTR 1024[ebp + edx*4]  )   \
+                                                        \
+    AS2(    mov   edx, z                            )   \
+    AS2(    shr   edx, 16                           )   \
+    AS2(    movzx edi, dl                           )   \
+    AS2(    xor   esi, DWORD PTR 2048[ebp + edi*4]  )   \
+    AS2(    movzx edx, dh                           )   \
+    AS2(    xor   esi, DWORD PTR 3072[ebp + edx*4]  )   \
+    AS2(    movd  edx, mm2                          )
+
+
+    // y = G2(b)  bytes(3,0,1,2)  [ put y into ecx for Rounds ]
+#define ASMG2(z, zl, zh)    \
+    AS2(    movd  mm7, ecx                          )   \
+    AS2(    movd  mm2, eax                          )   \
+    AS2(    mov   edi, z                            )   \
+    AS2(    shr   edi, 24                           )   \
+    AS2(    mov   ecx, DWORD PTR     [ebp + edi*4]  )   \
+    AS2(    movzx eax, zl                           )   \
+    AS2(    xor   ecx, DWORD PTR 1024[ebp + eax*4]  )   \
+                                                        \
+    AS2(    mov   eax, z                            )   \
+    AS2(    shr   eax, 16                           )   \
+    AS2(    movzx edi, zh                           )   \
+    AS2(    xor   ecx, DWORD PTR 2048[ebp + edi*4]  )   \
+    AS2(    movzx eax, al                           )   \
+    AS2(    xor   ecx, DWORD PTR 3072[ebp + eax*4]  )   \
+    AS2(    movd  eax, mm2                          )
+
+
+    // encrypt Round (n), 
+    // x = esi, k = ebp, edi open
+    // y is in ecx from G2, restore when done from mm7
+    //      before C (which be same register!)
+#define ASMENCROUND(N, A, A2, A3, B, B2, B3, C, D)      \
+    /* setup s_  */                                     \
+    AS2(    movd  ebp, mm1                          )   \
+    ASMG1(A, A2, A3)                                    \
+    ASMG2(B, B2, B3)                                    \
+    /* setup k  */                                      \
+    AS2(    movd  ebp, mm0                          )   \
+    /* x += y   */                                      \
+    AS2(    add   esi, ecx                          )   \
+    AS2(    add   ebp, 32                           )   \
+    /* y += x + k[2 * (n) + 1] */                       \
+    AS2(    add   ecx, esi                          )   \
+    AS2(    rol   D,   1                            )   \
+    AS2(    add   ecx, DWORD PTR [ebp + 8 * N + 4]  )   \
+	/* (d) = rotlFixed(d, 1) ^ y  */                    \
+    AS2(    xor   D,   ecx                          )   \
+    AS2(    movd  ecx, mm7                          )   \
+	/* (c) ^= x + k[2 * (n)] */                         \
+    AS2(    mov   edi, esi                          )   \
+    AS2(    add   edi, DWORD PTR [ebp + 8 * N]      )   \
+    AS2(    xor   C,   edi                          )   \
+	/* (c) = rotrFixed(c, 1) */                         \
+    AS2(    ror   C,   1                            )
+
+
+    // decrypt Round (n), 
+    // x = esi, k = ebp, edi open
+    // y is in ecx from G2, restore ecx from mm7 when done
+#define ASMDECROUND(N, A, A2, A3, B, B2, B3, C, D)      \
+    /* setup s_  */                                     \
+    AS2(    movd  ebp, mm1                          )   \
+    ASMG1(A, A2, A3)                                    \
+    ASMG2(B, B2, B3)                                    \
+    /* setup k  */                                      \
+    AS2(    movd  ebp, mm0                          )   \
+    /* x += y   */                                      \
+    AS2(    add   esi, ecx                          )   \
+    AS2(    add   ebp, 32                           )   \
+    /* y += x     */                                    \
+    AS2(    add   ecx, esi                          )   \
+	/* (d) ^= y + k[2 * (n) + 1] */                     \
+    AS2(    mov   edi, DWORD PTR [ebp + 8 * N + 4]  )   \
+    AS2(    add   edi, ecx                          )   \
+    AS2(    movd  ecx, mm7                          )   \
+    AS2(    xor   D,   edi                          )   \
+	/* (d) = rotrFixed(d, 1)     */                     \
+    AS2(    ror   D,   1                            )   \
+	/* (c) = rotlFixed(c, 1)     */                     \
+    AS2(    rol   C,   1                            )   \
+	/* (c) ^= (x + k[2 * (n)])   */                     \
+    AS2(    mov   edi, esi                          )   \
+    AS2(    add   edi, DWORD PTR [ebp + 8 * N]      )   \
+    AS2(    xor   C,   edi                          )
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void Twofish::AsmEncrypt(const byte* inBlock, byte* outBlock) const
+{
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    add   edi, 60                       ) // k_
+    #else
+        AS2(    add   edi, 56                       ) // k_
+    #endif
+
+    AS2(    mov   ebp, edi                      )
+
+    AS2(    mov   eax, DWORD PTR [esi]          ) // a
+    AS2(    movd  mm0, edi                      ) // store k_
+    AS2(    mov   ebx, DWORD PTR [esi +  4]     ) // b
+    AS2(    add   ebp, 160                      ) // s_[0]
+    AS2(    mov   ecx, DWORD PTR [esi +  8]     ) // c
+    AS2(    movd  mm1, ebp                      ) // store s_
+    AS2(    mov   edx, DWORD PTR [esi + 12]     ) // d
+    
+    AS2(    xor   eax, DWORD PTR [edi]          ) // k_[0]
+    AS2(    xor   ebx, DWORD PTR [edi +  4]     ) //   [1]
+    AS2(    xor   ecx, DWORD PTR [edi +  8]     ) //   [2]
+    AS2(    xor   edx, DWORD PTR [edi + 12]     ) //   [3]
+
+
+    ASMENCROUND( 0, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND( 1, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND( 2, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND( 3, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND( 4, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND( 5, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND( 6, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND( 7, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND( 8, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND( 9, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND(10, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND(11, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND(12, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND(13, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMENCROUND(14, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMENCROUND(15, ecx, cl, ch, edx, dl, dh, eax, ebx)
+
+
+    AS2(    movd  ebp, mm6                      )
+    AS2(    movd  esi, mm0                      ) // k_
+    #ifdef __GNUC__
+        AS2(    mov   edi, [ebp + 16]           ) // outBlock
+    #else
+        AS2(    mov   edi, [ebp + 12]           ) // outBlock
+    #endif
+
+    AS2(    xor   ecx, DWORD PTR [esi + 16]     ) // k_[4]
+    AS2(    xor   edx, DWORD PTR [esi + 20]     ) // k_[5]
+    AS2(    xor   eax, DWORD PTR [esi + 24]     ) // k_[6]
+    AS2(    xor   ebx, DWORD PTR [esi + 28]     ) // k_[7]
+
+    AS2(    mov   [edi],      ecx               ) // write out
+    AS2(    mov   [edi +  4], edx               ) // write out
+    AS2(    mov   [edi +  8], eax               ) // write out
+    AS2(    mov   [edi + 12], ebx               ) // write out
+
+
+    EPILOG()
+}
+
+
+#ifdef _MSC_VER
+    __declspec(naked) 
+#endif
+void Twofish::AsmDecrypt(const byte* inBlock, byte* outBlock) const
+{
+    PROLOG()
+
+    #ifdef OLD_GCC_OFFSET
+        AS2(    add   edi, 60                       ) // k_
+    #else
+        AS2(    add   edi, 56                       ) // k_
+    #endif
+
+    AS2(    mov   ebp, edi                      )
+
+    AS2(    mov   ecx, DWORD PTR [esi]          ) // c
+    AS2(    movd  mm0, edi                      ) // store k_
+    AS2(    mov   edx, DWORD PTR [esi +  4]     ) // d
+    AS2(    add   ebp, 160                      ) // s_[0]
+    AS2(    mov   eax, DWORD PTR [esi +  8]     ) // a
+    AS2(    movd  mm1, ebp                      ) // store s_
+    AS2(    mov   ebx, DWORD PTR [esi + 12]     ) // b
+
+    AS2(    xor   ecx, DWORD PTR [edi + 16]     ) // k_[4]
+    AS2(    xor   edx, DWORD PTR [edi + 20]     ) //   [5]
+    AS2(    xor   eax, DWORD PTR [edi + 24]     ) //   [6]
+    AS2(    xor   ebx, DWORD PTR [edi + 28]     ) //   [7]
+
+
+    ASMDECROUND(15, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND(14, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND(13, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND(12, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND(11, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND(10, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND( 9, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND( 8, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND( 7, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND( 6, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND( 5, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND( 4, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND( 3, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND( 2, eax, al, ah, ebx, bl, bh, ecx, edx)
+    ASMDECROUND( 1, ecx, cl, ch, edx, dl, dh, eax, ebx)
+    ASMDECROUND( 0, eax, al, ah, ebx, bl, bh, ecx, edx)
+
+
+    AS2(    movd  ebp, mm6                      )
+    AS2(    movd  esi, mm0                      ) // k_
+    #ifdef __GNUC__
+        AS2(    mov   edi, [ebp + 16]           ) // outBlock
+    #else
+        AS2(    mov   edi, [ebp + 12]           ) // outBlock
+    #endif
+
+    AS2(    xor   eax, DWORD PTR [esi     ]     ) // k_[0]
+    AS2(    xor   ebx, DWORD PTR [esi +  4]     ) // k_[1]
+    AS2(    xor   ecx, DWORD PTR [esi +  8]     ) // k_[2]
+    AS2(    xor   edx, DWORD PTR [esi + 12]     ) // k_[3]
+
+    AS2(    mov   [edi],      eax               ) // write out
+    AS2(    mov   [edi +  4], ebx               ) // write out
+    AS2(    mov   [edi +  8], ecx               ) // write out
+    AS2(    mov   [edi + 12], edx               ) // write out
+
+
+    EPILOG()
+}
+
+
+
+#endif // defined(DO_TWOFISH_ASM)
+
+
+
+
+
+} // namespace
+
+
diff --git a/extra/yassl/taocrypt/taocrypt.dsp b/extra/yassl/taocrypt/taocrypt.dsp
index 115ad0cb272..13b9a07419b 100644
--- a/extra/yassl/taocrypt/taocrypt.dsp
+++ b/extra/yassl/taocrypt/taocrypt.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
 # PROP Intermediate_Dir "Release"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX- /O2 /I "include" /I "..\mySTL" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /G6 /MT /W3 /O2 /I "include" /I "..\mySTL" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
 # PROP Intermediate_Dir "Debug"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX- /ZI /Od /I "include" /I "..\mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "..\mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -105,6 +105,14 @@ SOURCE=.\src\asn.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\bftables.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\blowfish.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\coding.cpp
 # End Source File
 # Begin Source File
@@ -159,6 +167,14 @@ SOURCE=.\src\rsa.cpp
 
 SOURCE=.\src\sha.cpp
 # End Source File
+# Begin Source File
+
+SOURCE=.\src\tftables.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\src\twofish.cpp
+# End Source File
 # End Group
 # Begin Group "Header Files"
 
@@ -185,6 +201,10 @@ SOURCE=.\include\block.hpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\include\blowfish.hpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\coding.hpp
 # End Source File
 # Begin Source File
@@ -241,6 +261,10 @@ SOURCE=.\include\modes.hpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\include\pwdbased.hpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\random.hpp
 # End Source File
 # Begin Source File
@@ -255,6 +279,18 @@ SOURCE=.\include\rsa.hpp
 
 SOURCE=.\include\sha.hpp
 # End Source File
+# Begin Source File
+
+SOURCE=.\include\twofish.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\type_traits.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\types.hpp
+# End Source File
 # End Group
 # End Target
 # End Project
diff --git a/extra/yassl/taocrypt/test.dsp b/extra/yassl/taocrypt/test.dsp
new file mode 100644
index 00000000000..a5e05ed0ac0
--- /dev/null
+++ b/extra/yassl/taocrypt/test.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "test.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "test___Win32_Release"
+# PROP BASE Intermediate_Dir "test___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "test\Release"
+# PROP Intermediate_Dir "test\Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "include" /I "../mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "test___Win32_Debug"
+# PROP BASE Intermediate_Dir "test___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "test\Debug"
+# PROP Intermediate_Dir "test\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "../mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "test - Win32 Release"
+# Name "test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\test\test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/extra/yassl/taocrypt/test.dsw b/extra/yassl/taocrypt/test.dsw
new file mode 100644
index 00000000000..b5c03bc6e03
--- /dev/null
+++ b/extra/yassl/taocrypt/test.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "test"=.\test.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/extra/yassl/taocrypt/test/Makefile.am b/extra/yassl/taocrypt/test/Makefile.am
new file mode 100644
index 00000000000..0b238f1e057
--- /dev/null
+++ b/extra/yassl/taocrypt/test/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I../include -I../../mySTL
+bin_PROGRAMS = test
+test_SOURCES = test.cpp
+test_LDFLAGS  = -L../src
+test_LDADD    = -ltaocrypt
+test_DEPENDENCIES = ../src/libtaocrypt.la
+test_CXXFLAGS = -DYASSL_PURE_C
+EXTRA_DIST = make.bat
diff --git a/extra/yassl/taocrypt/test/make.bat b/extra/yassl/taocrypt/test/make.bat
new file mode 100644
index 00000000000..e1a4cbce7cd
--- /dev/null
+++ b/extra/yassl/taocrypt/test/make.bat
@@ -0,0 +1,9 @@
+# quick and dirty build file for testing different MSDEVs
+setlocal 
+
+set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2
+
+cl %myFLAGS% test.cpp
+
+link.exe  /out:test.exe ../src/taocrypt.lib test.obj advapi32.lib
+
diff --git a/extra/yassl/taocrypt/test/memory.cpp b/extra/yassl/taocrypt/test/memory.cpp
new file mode 100644
index 00000000000..726c9c0ef54
--- /dev/null
+++ b/extra/yassl/taocrypt/test/memory.cpp
@@ -0,0 +1,312 @@
+// memory.cpp
+#include "../../include/lock.hpp"     // locking
+#include           // std::bad_alloc
+#include       // malloc
+#include       // memset
+#include       // ofstream
+#include       // stringstream
+#include       // assert
+#include       // setiosflags
+
+/*********************************************************************
+
+To use MemoryTracker merely add this file to your project
+No need to instantiate anything
+
+If your app is multi threaded define MULTI_THREADED
+
+*********************************************************************/
+
+
+// locals
+namespace {
+
+class MemoryTracker {
+    std::ofstream log_;
+public:
+    MemoryTracker();
+    ~MemoryTracker();
+private:
+    MemoryTracker(const MemoryTracker&);             // hide copy
+    MemoryTracker& operator=(const MemoryTracker&);  // and assign
+
+    void LogStats();
+};
+
+
+struct alloc_node {
+    alloc_node* left_;
+    alloc_node* right_;
+  
+    alloc_node() : left_(0), right_(0) {}
+};
+
+
+alloc_node* Root = 0;
+
+size_t Allocs    = 0;
+size_t DeAllocs  = 0;
+size_t Bytes     = 0;
+
+
+struct size_tracker {
+    size_t size_;
+    size_t count_;
+};
+
+size_tracker sizes[] = 
+{
+    {0,0},
+    {2,0},
+    {4,0},
+    {8,0},
+    {16,0},
+    {32,0},
+    {64,0},
+    {128,0},
+    {256,0},
+    {512,0},
+    {1024,0},
+    {2048,0},
+    {4096,0},
+    {8192,0},
+};
+
+const size_t size_elements(sizeof(sizes) / sizeof(size_tracker));
+
+bool Tracking(false);
+
+using   yaSSL::Mutex;
+typedef Mutex::Lock Lock;
+
+Mutex mutex;
+
+MemoryTracker theTracker;
+
+
+bool lookup(alloc_node*& find, void* key, alloc_node*& prev)
+{
+    bool found(false);
+
+    while (find) {
+        if (find == key) {
+            found = true;
+            break;
+        }
+        prev = find;
+        if (key < find)
+            find = find->left_;
+        else
+            find = find->right_;
+    }
+    return found;
+}
+
+
+// iterative insert
+void insert(alloc_node* entry)
+{
+    if (!Root) {
+        Root = entry;
+        return;
+    }
+       
+    alloc_node* tmp  = Root;
+    alloc_node* prev = 0;
+
+    if (lookup(tmp, entry, prev)) 
+        assert(0); // duplicate
+
+    if (entry < prev)
+        prev->left_  = entry;
+    else
+        prev->right_ = entry;
+}
+
+
+alloc_node* predecessorSwap(alloc_node* del)
+{
+    alloc_node* pred = del->left_;
+    alloc_node* predPrev = del;
+
+    while (pred->right_) {
+        predPrev = pred;
+        pred = pred->right_;
+    }
+    if (predPrev == del)
+        predPrev->left_  = pred->left_;
+    else
+        predPrev->right_ = pred->left_;
+
+    pred->left_  = del->left_;
+    pred->right_ = del->right_;
+
+    return pred;
+}
+
+
+// iterative remove
+void remove(void* ptr)
+{
+    alloc_node* del  = Root;
+    alloc_node* prev = 0;
+    alloc_node* replace = 0;
+
+    if ( lookup(del, ptr, prev) == false)
+        assert(0); // oops, not there
+
+    if (del->left_ && del->right_)          // two children
+        replace = predecessorSwap(del);
+    else if (!del->left_ && !del->right_)   // no children
+        replace = 0;
+    else                                    // one child
+        replace = (del->left_) ? del->left_ : del->right_;
+
+    if (del == Root)
+        Root = replace;
+    else if (prev->left_ == del)
+        prev->left_  = replace;
+    else
+        prev->right_ = replace;
+}
+
+
+typedef void (*fp)(alloc_node*, void*);
+
+void applyInOrder(alloc_node* root, fp f, void* arg)
+{
+    if (root == 0)
+        return;
+    
+    applyInOrder(root->left_,  f, arg);
+    f(root, arg);
+    applyInOrder(root->right_, f, arg);
+}
+
+
+void show(alloc_node* ptr, void* arg)
+{
+    std::ofstream* log = static_cast(arg);
+    *log << ptr << '\n';
+}
+
+
+MemoryTracker::MemoryTracker() : log_("memory.log")
+{
+#ifdef __GNUC__
+    // Force pool allocator to cleanup at exit
+    setenv("GLIBCPP_FORCE_NEW", "1", 0);
+#endif
+
+#ifdef _MSC_VER
+    // msvc6 needs to create Facility for ostream before main starts, otherwise
+    // if another ostream is created and destroyed in main scope, log stats
+    // will access a dead Facility reference (std::numput)
+    int msvcFac = 6;
+    log_ << "MSVC " << msvcFac << "workaround" << std::endl; 
+#endif
+
+
+    Tracking = true;
+}
+
+
+MemoryTracker::~MemoryTracker()
+{
+    // stop tracking before log (which will alloc on output)
+    Tracking = false;
+    LogStats();
+
+    //assert(Allocs == DeAllocs);
+    //assert(Root == 0);
+}
+
+
+void MemoryTracker::LogStats()
+{
+    log_ << "Number of Allocs:     " << Allocs    << '\n';
+    log_ << "Number of DeAllocs:   " << DeAllocs  << '\n';
+    log_ << "Number of bytes used: " << Bytes     << '\n';
+
+    log_ << "Alloc size table:\n";
+    log_ << " Bytes " << '\t' << "   Times\n";
+
+    for (size_t i = 0; i < size_elements; ++i) {
+        log_ << " " << sizes[i].size_  << "  " << '\t';
+        log_ << std::setiosflags(std::ios::right) << std::setw(8);
+        log_ << sizes[i].count_ << '\n';
+    }
+
+    if (Allocs != DeAllocs) {
+        log_<< "Showing new'd allocs with no deletes" << '\n';
+        applyInOrder(Root, show, &log_);
+    }
+    log_.flush();
+}
+
+
+// return power of 2 up to size_tracker elements
+size_t powerOf2(size_t sz)
+{
+    size_t shifts = 0;
+
+    if (sz)
+        sz -= 1;
+    else
+        return 0;
+	   
+    while (sz) {
+        sz >>= 1;
+        ++shifts;
+    }
+
+    return shifts < size_elements ? shifts : size_elements;
+}
+
+
+} // namespace local
+
+
+void* operator new(size_t sz)
+{
+    // put alloc node in front of requested memory
+    void* ptr = malloc(sz + sizeof(alloc_node));
+    if (ptr) {
+        if (Tracking) {
+            Lock l(mutex);
+            ++Allocs;
+            Bytes += sz;
+            ++sizes[powerOf2(sz)].count_;
+            insert(new (ptr) alloc_node);
+        }
+        return static_cast(ptr) + sizeof(alloc_node);
+    }
+    else
+        assert(0);
+}
+
+
+void operator delete(void* ptr)
+{
+    if (ptr) {
+        ptr = static_cast(ptr) - sizeof(alloc_node);  // correct offset
+        if (Tracking) {
+            Lock l(mutex);
+            ++DeAllocs;
+            remove(ptr);
+        }
+        free(ptr);
+    }
+}
+
+
+void* operator new[](size_t sz)
+{
+    return ::operator new(sz);
+}
+
+
+void operator delete[](void* ptr)
+{
+    ::operator delete(ptr);
+}
diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp
new file mode 100644
index 00000000000..b8618b18d47
--- /dev/null
+++ b/extra/yassl/taocrypt/test/test.cpp
@@ -0,0 +1,941 @@
+// test.cpp
+// test taocrypt functionality
+
+#include 
+#include 
+
+#include "runtime.hpp"
+#include "sha.hpp"
+#include "md5.hpp"
+#include "md2.hpp"
+#include "ripemd.hpp"
+#include "hmac.hpp"
+#include "arc4.hpp"
+#include "des.hpp"
+#include "rsa.hpp"
+#include "dsa.hpp"
+#include "aes.hpp"
+#include "twofish.hpp"
+#include "blowfish.hpp"
+#include "asn.hpp"
+#include "dh.hpp"
+#include "coding.hpp"
+#include "random.hpp"
+#include "pwdbased.hpp"
+
+
+
+using TaoCrypt::byte;
+using TaoCrypt::word32;
+using TaoCrypt::SHA;
+using TaoCrypt::MD5;
+using TaoCrypt::MD2;
+using TaoCrypt::RIPEMD160;
+using TaoCrypt::HMAC;
+using TaoCrypt::ARC4;
+using TaoCrypt::DES_EDE3_CBC_Encryption;
+using TaoCrypt::DES_EDE3_CBC_Decryption;
+using TaoCrypt::DES_CBC_Encryption;
+using TaoCrypt::DES_CBC_Decryption;
+using TaoCrypt::DES_ECB_Encryption;
+using TaoCrypt::DES_ECB_Decryption;
+using TaoCrypt::AES_CBC_Encryption;
+using TaoCrypt::AES_CBC_Decryption;
+using TaoCrypt::AES_ECB_Encryption;
+using TaoCrypt::AES_ECB_Decryption;
+using TaoCrypt::Twofish_CBC_Encryption;
+using TaoCrypt::Twofish_CBC_Decryption;
+using TaoCrypt::Twofish_ECB_Encryption;
+using TaoCrypt::Twofish_ECB_Decryption;
+using TaoCrypt::Blowfish_CBC_Encryption;
+using TaoCrypt::Blowfish_CBC_Decryption;
+using TaoCrypt::Blowfish_ECB_Encryption;
+using TaoCrypt::Blowfish_ECB_Decryption;
+using TaoCrypt::RSA_PrivateKey;
+using TaoCrypt::RSA_PublicKey;
+using TaoCrypt::DSA_PrivateKey;
+using TaoCrypt::DSA_PublicKey;
+using TaoCrypt::DSA_Signer;
+using TaoCrypt::DSA_Verifier;
+using TaoCrypt::RSAES_Encryptor;
+using TaoCrypt::RSAES_Decryptor;
+using TaoCrypt::Source;
+using TaoCrypt::FileSource;
+using TaoCrypt::FileSource;
+using TaoCrypt::HexDecoder;
+using TaoCrypt::HexEncoder;
+using TaoCrypt::Base64Decoder;
+using TaoCrypt::Base64Encoder;
+using TaoCrypt::CertDecoder;
+using TaoCrypt::DH;
+using TaoCrypt::EncodeDSA_Signature;
+using TaoCrypt::DecodeDSA_Signature;
+using TaoCrypt::PBKDF2_HMAC;
+using TaoCrypt::tcArrayDelete;
+
+
+
+struct testVector {
+    byte*  input_;
+    byte*  output_; 
+    size_t inLen_;
+    size_t outLen_;
+
+    testVector(const char* in, const char* out) : input_((byte*)in),
+               output_((byte*)out), inLen_(strlen(in)), outLen_(strlen(out)) {}
+};
+
+void file_test(int, char**);
+int  sha_test();
+int  md5_test();
+int  md2_test();
+int  ripemd_test();
+int  hmac_test();
+int  arc4_test();
+int  des_test();
+int  aes_test();
+int  twofish_test();
+int  blowfish_test();
+int  rsa_test();
+int  dsa_test();
+int  dh_test();
+int  pwdbased_test();
+
+TaoCrypt::RandomNumberGenerator rng;
+
+
+void err_sys(const char* msg, int es)
+{
+    printf("%s", msg);
+    exit(es);    
+}
+
+// func_args from test.hpp, so don't have to pull in other junk
+struct func_args {
+    int    argc;
+    char** argv;
+    int    return_code;
+};
+
+
+/* 
+   DES, AES, Blowfish, and Twofish need aligned (4 byte) input/output for
+   processing, can turn this off by setting gpBlock(assumeAligned = false)
+   but would hurt performance.  yaSSL always uses dynamic memory so we have
+   at least 8 byte alignment.  This test tried to force alignment for stack
+   variables (for convenience) but some compiler versions and optimizations
+   seemed to be off.  So we have msgTmp variable which we copy into dynamic
+   memory at runtime to ensure proper alignment, along with plain/cipher.
+   Whew!
+*/
+const byte msgTmp[] = { // "now is the time for all " w/o trailing 0
+    0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
+    0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
+    0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
+};
+
+byte* msg    = 0;   // for block cipher input
+byte* plain  = 0;   // for cipher decrypt comparison 
+byte* cipher = 0;   // block output
+
+
+void taocrypt_test(void* args)
+{
+    ((func_args*)args)->return_code = -1; // error state
+    
+    msg    = NEW_TC byte[24];
+    plain  = NEW_TC byte[24];
+    cipher = NEW_TC byte[24];
+
+    memcpy(msg, msgTmp, 24);
+
+    int ret = 0;
+    if ( (ret = sha_test()) ) 
+        err_sys("SHA      test failed!\n", ret);
+    else
+        printf( "SHA      test passed!\n");
+
+    if ( (ret = md5_test()) ) 
+        err_sys("MD5      test failed!\n", ret);
+    else
+        printf( "MD5      test passed!\n");
+
+    if ( (ret = md2_test()) ) 
+        err_sys("MD2      test failed!\n", ret);
+    else
+        printf( "MD2      test passed!\n");
+
+    if ( (ret = ripemd_test()) )
+        err_sys("RIPEMD   test failed!\n", ret);
+    else
+        printf( "RIPEMD   test passed!\n");
+
+    if ( ( ret = hmac_test()) )
+        err_sys("HMAC     test failed!\n", ret);
+    else
+        printf( "HMAC     test passed!\n");
+
+    if ( (ret = arc4_test()) )
+        err_sys("ARC4     test failed!\n", ret);
+    else
+        printf( "ARC4     test passed!\n");
+
+    if ( (ret = des_test()) )
+        err_sys("DES      test failed!\n", ret);
+    else
+        printf( "DES      test passed!\n");
+
+    if ( (ret = aes_test()) )
+        err_sys("AES      test failed!\n", ret);
+    else
+        printf( "AES      test passed!\n");
+
+    if ( (ret = twofish_test()) )
+        err_sys("Twofish  test failed!\n", ret);
+    else
+        printf( "Twofish  test passed!\n");
+
+    if ( (ret = blowfish_test()) )
+        err_sys("Blowfish test failed!\n", ret);
+    else
+        printf( "Blowfish test passed!\n");
+
+    if ( (ret = rsa_test()) )
+        err_sys("RSA      test failed!\n", ret);
+    else
+        printf( "RSA      test passed!\n");
+
+    if ( (ret = dh_test()) )
+        err_sys("DH       test failed!\n", ret);
+    else
+        printf( "DH       test passed!\n");
+
+    if ( (ret = dsa_test()) )
+        err_sys("DSA      test failed!\n", ret);
+    else
+        printf( "DSA      test passed!\n");
+
+    if ( (ret = pwdbased_test()) )
+        err_sys("PBKDF2   test failed!\n", ret);
+    else
+        printf( "PBKDF2   test passed!\n");
+
+    tcArrayDelete(cipher);
+    tcArrayDelete(plain);
+    tcArrayDelete(msg);
+
+    ((func_args*)args)->return_code = ret;
+}
+
+
+// so overall tests can pull in test function 
+#ifndef NO_MAIN_DRIVER
+
+    int main(int argc, char** argv)
+    {
+        func_args args;
+
+        args.argc = argc;
+        args.argv = argv;
+
+        taocrypt_test(&args);
+        return args.return_code;
+    }
+
+#endif // NO_MAIN_DRIVER
+
+
+void file_test(char* file, byte* check)
+{
+    FILE* f;
+    int   i(0);
+    MD5   md5;
+    byte  buf[1024];
+    byte  md5sum[MD5::DIGEST_SIZE];
+    
+    if( !( f = fopen( file, "rb" ) )) {
+        printf("Can't open %s\n", file);
+        return;
+    }
+    while( ( i = fread(buf, 1, sizeof(buf), f )) > 0 )
+        md5.Update(buf, i);
+    
+    md5.Final(md5sum);
+    memcpy(check, md5sum, sizeof(md5sum));
+
+    for(int j = 0; j < MD5::DIGEST_SIZE; ++j ) 
+        printf( "%02x", md5sum[j] );
+   
+    printf("  %s\n", file);
+
+    fclose(f);
+}
+
+
+int sha_test()
+{
+    SHA  sha;
+    byte hash[SHA::DIGEST_SIZE];
+
+    testVector test_sha[] =
+    {
+        testVector("abc", 
+                 "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2"
+                 "\x6C\x9C\xD0\xD8\x9D"),
+        testVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+                 "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29"
+                 "\xE5\xE5\x46\x70\xF1"),
+        testVector("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                 "aaaaaa", 
+                 "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44"
+                 "\x2A\x25\xEC\x64\x4D"),
+        testVector("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                 "aaaaaaaaaa",
+                 "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7"
+                 "\x53\x99\x5E\x26\xA0")  
+    };
+
+    int times( sizeof(test_sha) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        sha.Update(test_sha[i].input_, test_sha[i].inLen_);
+        sha.Final(hash);
+
+        if (memcmp(hash, test_sha[i].output_, SHA::DIGEST_SIZE) != 0)
+            return -1 - i;
+    }
+
+    return 0;
+}
+
+
+int md5_test()
+{
+    MD5  md5;
+    byte hash[MD5::DIGEST_SIZE];
+
+    testVector test_md5[] =
+    {
+        testVector("abc", 
+                 "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f"
+                 "\x72"),
+        testVector("message digest", 
+                 "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61"
+                 "\xd0"),
+        testVector("abcdefghijklmnopqrstuvwxyz",
+                 "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1"
+                 "\x3b"),
+        testVector("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345"
+                 "6789",
+                 "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d"
+                 "\x9f"),
+        testVector("1234567890123456789012345678901234567890123456789012345678"
+                 "9012345678901234567890",
+                 "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6"
+                 "\x7a")
+    };
+
+    int times( sizeof(test_md5) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        md5.Update(test_md5[i].input_, test_md5[i].inLen_);
+        md5.Final(hash);
+
+        if (memcmp(hash, test_md5[i].output_, MD5::DIGEST_SIZE) != 0)
+            return -5 - i;
+    }
+
+    return 0;
+}
+
+
+int md2_test()
+{
+    MD2  md5;
+    byte hash[MD2::DIGEST_SIZE];
+
+    testVector test_md2[] =
+    {
+        testVector("",
+                   "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69"
+                   "\x27\x73"),
+        testVector("a",
+                   "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0"
+                   "\xb5\xd1"),
+        testVector("abc",
+                   "\xda\x85\x3b\x0d\x3f\x88\xd9\x9b\x30\x28\x3a\x69\xe6\xde"
+                   "\xd6\xbb"),
+        testVector("message digest",
+                   "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe"
+                   "\x06\xb0"),
+        testVector("abcdefghijklmnopqrstuvwxyz",
+                   "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47"
+                   "\x94\x0b"),
+        testVector("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+                   "0123456789",
+                   "\xda\x33\xde\xf2\xa4\x2d\xf1\x39\x75\x35\x28\x46\xc3\x03"
+                   "\x38\xcd"),
+        testVector("12345678901234567890123456789012345678901234567890123456"
+                   "789012345678901234567890",
+                   "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3"
+                   "\xef\xd8")
+    };
+
+    int times( sizeof(test_md2) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        md5.Update(test_md2[i].input_, test_md2[i].inLen_);
+        md5.Final(hash);
+
+        if (memcmp(hash, test_md2[i].output_, MD2::DIGEST_SIZE) != 0)
+            return -10 - i;
+    }
+
+    return 0;
+}
+
+
+int ripemd_test()
+{
+    RIPEMD160  ripe160;
+    byte hash[RIPEMD160::DIGEST_SIZE];
+
+    testVector test_ripemd[] =
+    {
+        testVector("",
+                   "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8"
+                   "\xf5\x48\xb2\x25\x8d\x31"),
+        testVector("a",
+                   "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae\x34\x7b\xe6\xf4"
+                   "\xdc\x83\x5a\x46\x7f\xfe"),
+        testVector("abc",
+                   "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6"
+                   "\xb0\x87\xf1\x5a\x0b\xfc"),
+        testVector("message digest",
+                   "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8\x81\xb1\x23\xa8"
+                   "\x5f\xfa\x21\x59\x5f\x36"),
+        testVector("abcdefghijklmnopqrstuvwxyz",
+                   "\xf7\x1c\x27\x10\x9c\x69\x2c\x1b\x56\xbb\xdc\xeb\x5b\x9d"
+                   "\x28\x65\xb3\x70\x8d\xbc"),
+        testVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+                   "\x12\xa0\x53\x38\x4a\x9c\x0c\x88\xe4\x05\xa0\x6c\x27\xdc"
+                   "\xf4\x9a\xda\x62\xeb\x2b"),
+        testVector("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
+                   "456789",
+                   "\xb0\xe2\x0b\x6e\x31\x16\x64\x02\x86\xed\x3a\x87\xa5\x71"
+                   "\x30\x79\xb2\x1f\x51\x89"),
+        testVector("12345678901234567890123456789012345678901234567890123456"
+                   "789012345678901234567890",
+                   "\x9b\x75\x2e\x45\x57\x3d\x4b\x39\xf4\xdb\xd3\x32\x3c\xab"
+                   "\x82\xbf\x63\x32\x6b\xfb"),
+    };
+
+    int times( sizeof(test_ripemd) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        ripe160.Update(test_ripemd[i].input_, test_ripemd[i].inLen_);
+        ripe160.Final(hash);
+
+        if (memcmp(hash, test_ripemd[i].output_, RIPEMD160::DIGEST_SIZE) != 0)
+            return -100 - i;
+    }
+
+    return 0;
+}
+
+
+int hmac_test()
+{
+    HMAC hmacMD5;
+    byte hash[MD5::DIGEST_SIZE];
+
+    const char* keys[]=
+    {
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+        "Jefe",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+    };
+
+    testVector test_hmacMD5[] = 
+    {
+        testVector("Hi There",
+                 "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc"
+                 "\x9d"),
+        testVector("what do ya want for nothing?",
+                 "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7"
+                 "\x38"),
+        testVector("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+                 "\xDD\xDD\xDD\xDD\xDD\xDD",
+                 "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3"
+                 "\xf6")
+    };
+
+    int times( sizeof(test_hmacMD5) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        hmacMD5.SetKey((byte*)keys[i], strlen(keys[i]));
+        hmacMD5.Update(test_hmacMD5[i].input_, test_hmacMD5[i].inLen_);
+        hmacMD5.Final(hash);
+
+        if (memcmp(hash, test_hmacMD5[i].output_, MD5::DIGEST_SIZE) != 0)
+            return -20 - i;
+    }
+
+    return 0;
+}
+
+
+int arc4_test()
+{
+    byte cipher[16];
+    byte plain[16];
+
+    const char* keys[] = 
+    {           
+        "\x01\x23\x45\x67\x89\xab\xcd\xef",
+        "\x01\x23\x45\x67\x89\xab\xcd\xef",
+        "\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\xef\x01\x23\x45"
+    };
+
+    testVector test_arc4[] =
+    {
+        testVector("\x01\x23\x45\x67\x89\xab\xcd\xef",
+                   "\x75\xb7\x87\x80\x99\xe0\xc5\x96"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\x74\x94\xc2\xe7\x10\x4b\x08\x79"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\xde\x18\x89\x41\xa3\x37\x5d\x3a"),
+        testVector("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+                   "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf\xbd\x61")
+    };
+
+
+    int times( sizeof(test_arc4) / sizeof(testVector) );
+    for (int i = 0; i < times; ++i) {
+        ARC4::Encryption enc;
+        ARC4::Decryption dec;
+
+        enc.SetKey((byte*)keys[i], strlen(keys[i]));
+        dec.SetKey((byte*)keys[i], strlen(keys[i]));
+
+        enc.Process(cipher, test_arc4[i].input_, test_arc4[i].outLen_);
+        dec.Process(plain,  cipher, test_arc4[i].outLen_);
+
+        if (memcmp(plain, test_arc4[i].input_, test_arc4[i].outLen_))
+            return -30 - i;
+
+        if (memcmp(cipher, test_arc4[i].output_, test_arc4[i].outLen_))
+            return -40 - i;
+    }
+
+    return 0;
+}
+
+
+int des_test()
+{
+    //ECB mode
+    DES_ECB_Encryption enc;
+    DES_ECB_Decryption dec;
+
+    const int sz = TaoCrypt::DES_BLOCK_SIZE * 3;
+    const byte key[] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef };
+    const byte iv[] =  { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef };
+
+    enc.SetKey(key, sizeof(key));
+    enc.Process(cipher, msg, sz);
+    dec.SetKey(key, sizeof(key));
+    dec.Process(plain, cipher, sz);
+
+    if (memcmp(plain, msg, sz))
+        return -50;
+
+    const byte verify1[] = 
+    {
+        0xf9,0x99,0xb8,0x8e,0xaf,0xea,0x71,0x53,
+        0x6a,0x27,0x17,0x87,0xab,0x88,0x83,0xf9,
+        0x89,0x3d,0x51,0xec,0x4b,0x56,0x3b,0x53
+    };
+
+    if (memcmp(cipher, verify1, sz))
+        return -51;
+
+    // CBC mode
+    DES_CBC_Encryption enc2;
+    DES_CBC_Decryption dec2;
+
+    enc2.SetKey(key, sizeof(key), iv);
+    enc2.Process(cipher, msg, sz);
+    dec2.SetKey(key, sizeof(key), iv);
+    dec2.Process(plain, cipher, sz);
+
+    if (memcmp(plain, msg, sz))
+        return -52;
+
+    const byte verify2[] = 
+    {
+        0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8,
+        0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73,
+        0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b
+    };
+
+    if (memcmp(cipher, verify2, sz))
+        return -53;
+
+    // EDE3 CBC mode
+    DES_EDE3_CBC_Encryption enc3;
+    DES_EDE3_CBC_Decryption dec3;
+
+    const byte key3[] = 
+    {
+        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+        0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
+        0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
+    };
+    const byte iv3[] = 
+    {
+        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
+        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+        0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
+        
+    };
+
+    enc3.SetKey(key3, sizeof(key3), iv3);
+    enc3.Process(cipher, msg, sz);
+    dec3.SetKey(key3, sizeof(key3), iv3);
+    dec3.Process(plain, cipher, sz);
+
+    if (memcmp(plain, msg, sz))
+        return -54;
+
+    const byte verify3[] = 
+    {
+        0x08,0x8a,0xae,0xe6,0x9a,0xa9,0xc1,0x13,
+        0x93,0x7d,0xf7,0x3a,0x11,0x56,0x66,0xb3,
+        0x18,0xbc,0xbb,0x6d,0xd2,0xb1,0x16,0xda
+    };
+
+    if (memcmp(cipher, verify3, sz))
+        return -55;
+
+    return 0;
+}
+
+
+int aes_test()
+{
+    AES_CBC_Encryption enc;
+    AES_CBC_Decryption dec;
+    const int bs(TaoCrypt::AES::BLOCK_SIZE);
+
+    byte key[] = "0123456789abcdef   ";  // align
+    byte iv[]  = "1234567890abcdef   ";  // align
+
+    enc.SetKey(key, bs, iv);
+    dec.SetKey(key, bs, iv);
+
+    enc.Process(cipher, msg, bs);
+    dec.Process(plain, cipher, bs);
+
+    if (memcmp(plain, msg, bs))
+        return -60;
+
+    const byte verify[] = 
+    {
+        0x95,0x94,0x92,0x57,0x5f,0x42,0x81,0x53,
+        0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb
+    };
+
+    if (memcmp(cipher, verify, bs))
+        return -61;
+
+    AES_ECB_Encryption enc2;
+    AES_ECB_Decryption dec2;
+
+    enc2.SetKey(key, bs, iv);
+    dec2.SetKey(key, bs, iv);
+
+    enc2.Process(cipher, msg, bs);
+    dec2.Process(plain, cipher, bs);
+
+    if (memcmp(plain, msg, bs))
+        return -62;
+
+    const byte verify2[] = 
+    {
+        0xd0,0xc9,0xd9,0xc9,0x40,0xe8,0x97,0xb6,
+        0xc8,0x8c,0x33,0x3b,0xb5,0x8f,0x85,0xd1
+    };
+
+    if (memcmp(cipher, verify2, bs))
+        return -63;
+
+    return 0;
+}
+
+
+int twofish_test()
+{
+    Twofish_CBC_Encryption enc;
+    Twofish_CBC_Decryption dec;
+    const int bs(TaoCrypt::Twofish::BLOCK_SIZE);
+
+    byte key[] = "0123456789abcdef   ";  // align
+    byte iv[]  = "1234567890abcdef   ";  // align
+
+    enc.SetKey(key, bs, iv);
+    dec.SetKey(key, bs, iv);
+
+    enc.Process(cipher, msg, bs);
+    dec.Process(plain, cipher, bs);
+
+    if (memcmp(plain, msg, bs))
+        return -60;
+
+    const byte verify[] = 
+    {
+        0xD2,0xD7,0x47,0x47,0x4A,0x65,0x4E,0x16,
+        0x21,0x03,0x58,0x79,0x5F,0x02,0x27,0x2C
+    };
+
+    if (memcmp(cipher, verify, bs))
+        return -61;
+
+    Twofish_ECB_Encryption enc2;
+    Twofish_ECB_Decryption dec2;
+
+    enc2.SetKey(key, bs, iv);
+    dec2.SetKey(key, bs, iv);
+
+    enc2.Process(cipher, msg, bs);
+    dec2.Process(plain, cipher, bs);
+
+    if (memcmp(plain, msg, bs))
+        return -62;
+
+    const byte verify2[] = 
+    {
+        0x3B,0x6C,0x63,0x10,0x34,0xAB,0xB2,0x87,
+        0xC4,0xCD,0x6B,0x91,0x14,0xC5,0x3A,0x09
+    };
+
+    if (memcmp(cipher, verify2, bs))
+        return -63;
+
+    return 0;
+}
+
+
+int blowfish_test()
+{
+    Blowfish_CBC_Encryption enc;
+    Blowfish_CBC_Decryption dec;
+    const int bs(TaoCrypt::Blowfish::BLOCK_SIZE);
+
+    byte key[] = "0123456789abcdef   ";  // align
+    byte iv[]  = "1234567890abcdef   ";  // align
+
+    enc.SetKey(key, 16, iv);
+    dec.SetKey(key, 16, iv);
+
+    enc.Process(cipher, msg, bs * 2);
+    dec.Process(plain, cipher, bs * 2);
+
+    if (memcmp(plain, msg, bs))
+        return -60;
+
+    const byte verify[] = 
+    {
+        0x0E,0x26,0xAA,0x29,0x11,0x25,0xAB,0xB5,
+        0xBC,0xD9,0x08,0xC4,0x94,0x6C,0x89,0xA3
+    };
+
+    if (memcmp(cipher, verify, bs))
+        return -61;
+
+    Blowfish_ECB_Encryption enc2;
+    Blowfish_ECB_Decryption dec2;
+
+    enc2.SetKey(key, 16, iv);
+    dec2.SetKey(key, 16, iv);
+
+    enc2.Process(cipher, msg, bs * 2);
+    dec2.Process(plain, cipher, bs * 2);
+
+    if (memcmp(plain, msg, bs))
+        return -62;
+
+    const byte verify2[] = 
+    {
+        0xE7,0x42,0xB9,0x37,0xC8,0x7D,0x93,0xCA,
+        0x8F,0xCE,0x39,0x32,0xDE,0xD7,0xBC,0x5B
+    };
+
+    if (memcmp(cipher, verify2, bs))
+        return -63;
+
+    return 0;
+}
+
+
+int rsa_test()
+{
+    Source source;
+    FileSource("../certs/client-key.der", source);
+    if (source.size() == 0) {
+        FileSource("../../certs/client-key.der", source);  // for testsuite
+        if (source.size() == 0) {
+            FileSource("../../../certs/client-key.der", source); // Debug dir
+            if (source.size() == 0)
+                err_sys("where's your certs dir?", -79);
+        }
+    }
+    RSA_PrivateKey priv(source);
+
+    RSAES_Encryptor enc(priv);
+    byte message[] = "Everyone gets Friday off.";
+    const int len(strlen((char*)message));
+    byte cipher[64];
+    enc.Encrypt(message, len, cipher, rng);
+
+    RSAES_Decryptor dec(priv);
+    byte plain[64];
+    dec.Decrypt(cipher, sizeof(plain), plain, rng);
+
+    if (memcmp(plain, message, len))
+        return -70;
+
+    dec.SSL_Sign(message, len, cipher, rng);
+    if (!enc.SSL_Verify(message, len, cipher))
+        return -71;
+
+
+    // test decode   
+    Source source2;
+    FileSource("../certs/client-cert.der", source2);
+    if (source2.size() == 0) {
+        FileSource("../../certs/client-cert.der", source2);  // for testsuite
+        if (source2.size() == 0) {
+            FileSource("../../../certs/client-cert.der", source2); // Debug dir
+            if (source2.size() == 0)
+                err_sys("where's your certs dir?", -79);
+        }
+    }
+    CertDecoder cd(source2, true, 0, false, CertDecoder::CA);
+    Source source3(cd.GetPublicKey().GetKey(), cd.GetPublicKey().size());
+    RSA_PublicKey pub(source3);
+ 
+    return 0;
+}
+
+
+int dh_test()
+{
+    Source source;
+    FileSource("../certs/dh1024.dat", source);
+    if (source.size() == 0) {
+        FileSource("../../certs/dh1024.dat", source);  // for testsuite
+        if (source.size() == 0) {
+            FileSource("../../../certs/dh1024.dat", source); // win32 Debug dir
+            if (source.size() == 0)
+                err_sys("where's your certs dir?", -79);
+        }
+    }
+    HexDecoder hDec(source);
+
+    DH dh(source);
+
+    byte pub[128];
+    byte priv[128];
+    byte agree[128];
+    byte pub2[128];
+    byte priv2[128];
+    byte agree2[128];
+
+    DH dh2(dh);
+
+    dh.GenerateKeyPair(rng, priv, pub);
+    dh2.GenerateKeyPair(rng, priv2, pub2);
+    dh.Agree(agree, priv, pub2); 
+    dh2.Agree(agree2, priv2, pub);
+
+    
+    if ( memcmp(agree, agree2, dh.GetByteLength()) )
+        return -80;
+
+    return 0;
+}
+
+
+int dsa_test()
+{
+    Source source;
+    FileSource("../certs/dsa512.der", source);
+    if (source.size() == 0) {
+        FileSource("../../certs/dsa512.der", source);  // for testsuite
+        if (source.size() == 0) {
+            FileSource("../../../certs/dsa512.der", source); // win32 Debug dir
+            if (source.size() == 0)
+                err_sys("where's your certs dir?", -89);
+        }
+    }
+
+    const char msg[] = "this is the message";
+    byte signature[40];
+
+    DSA_PrivateKey priv(source);
+    DSA_Signer signer(priv);
+
+    SHA sha;
+    byte digest[SHA::DIGEST_SIZE];
+    sha.Update((byte*)msg, sizeof(msg));
+    sha.Final(digest);
+
+    signer.Sign(digest, signature, rng);
+
+    byte encoded[sizeof(signature) + 6];
+    byte decoded[40];
+
+    word32 encSz = EncodeDSA_Signature(signer.GetR(), signer.GetS(), encoded);
+    DecodeDSA_Signature(decoded, encoded, encSz);
+
+    DSA_PublicKey pub(priv);
+    DSA_Verifier verifier(pub);
+
+    if (!verifier.Verify(digest, decoded))
+        return -90;
+
+    return 0;
+}
+
+
+int pwdbased_test()
+{
+    PBKDF2_HMAC pb;
+
+    byte derived[32];
+    const byte pwd1[] = "password   ";  // align
+    const byte salt[]  = { 0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 };
+    
+    pb.DeriveKey(derived, 8, pwd1, 8, salt, sizeof(salt), 5);
+
+    const byte verify1[] = { 0xD1, 0xDA, 0xA7, 0x86, 0x15, 0xF2, 0x87, 0xE6 };
+
+    if ( memcmp(derived, verify1, sizeof(verify1)) )
+        return -101;
+
+
+    const byte pwd2[] = "All n-entities must communicate with other n-entities"
+                        " via n-1 entiteeheehees   ";  // align
+
+    pb.DeriveKey(derived, 24, pwd2, 76, salt, sizeof(salt), 500);
+
+    const byte verify2[] = { 0x6A, 0x89, 0x70, 0xBF, 0x68, 0xC9, 0x2C, 0xAE,
+                             0xA8, 0x4A, 0x8D, 0xF2, 0x85, 0x10, 0x85, 0x86,
+                             0x07, 0x12, 0x63, 0x80, 0xCC, 0x47, 0xAB, 0x2D
+    };
+
+    if ( memcmp(derived, verify2, sizeof(verify2)) )
+        return -102;
+
+    return 0;
+}
diff --git a/extra/yassl/testsuite/Makefile.am b/extra/yassl/testsuite/Makefile.am
new file mode 100644
index 00000000000..d91822f609e
--- /dev/null
+++ b/extra/yassl/testsuite/Makefile.am
@@ -0,0 +1,11 @@
+INCLUDES = -I../include -I../taocrypt/include -I../mySTL
+bin_PROGRAMS       = testsuite
+testsuite_SOURCES  = testsuite.cpp ../taocrypt/test/test.cpp \
+	../examples/client/client.cpp ../examples/server/server.cpp \
+	../examples/echoclient/echoclient.cpp \
+	../examples/echoserver/echoserver.cpp
+testsuite_LDFLAGS  = -L../src/ -L../taocrypt/src
+testsuite_CXXFLAGS = -DYASSL_PURE_C -DNO_MAIN_DRIVER
+testsuite_LDADD    = -lyassl -ltaocrypt
+testsuite_DEPENDENCIES = ../src/libyassl.la ../taocrypt/src/libtaocrypt.la
+EXTRA_DIST = testsuite.dsp test.hpp input quit make.bat
diff --git a/extra/yassl/testsuite/input b/extra/yassl/testsuite/input
new file mode 100644
index 00000000000..d16cbc40750
--- /dev/null
+++ b/extra/yassl/testsuite/input
@@ -0,0 +1,107 @@
+// testsuite.cpp
+
+#include "test.hpp"
+#include "md5.hpp"
+
+typedef unsigned char byte;
+
+void taocrypt_test(void*);
+void file_test(char*, byte*);
+
+void client_test(void*);
+void echoclient_test(void*);
+
+THREAD_RETURN YASSL_API server_test(void*);
+THREAD_RETURN YASSL_API echoserver_test(void*);
+
+int main(int argc, char** argv)
+{
+    func_args args(argc, argv);
+    func_args server_args(args);
+
+    // *** Crypto Test ***
+    taocrypt_test(&args);
+    assert(args.return_code == 0);
+    
+    
+    // *** Simple yaSSL client server test ***
+    THREAD_TYPE thread;
+
+    start_thread(server_test, &server_args, &thread);
+    client_test(&args);
+
+    assert(args.return_code == 0);
+    join_thread(thread);
+    assert(server_args.return_code == 0);
+    
+
+    // *** Echo input yaSSL client server test ***
+    start_thread(echoserver_test, &server_args, &thread);
+    func_args echo_args;
+
+            // setup args
+    echo_args.argc = 3;
+    echo_args.argv = new char*[echo_args.argc];
+    for (int i = 0; i < echo_args.argc; i++)
+        echo_args.argv[i] = new char[32];
+   
+    strcpy(echo_args.argv[0], "echoclient");
+    strcpy(echo_args.argv[1], "input");
+    strcpy(echo_args.argv[2], "output");
+    remove("output");
+
+            // make sure OK
+    echoclient_test(&echo_args);
+    assert(echo_args.return_code == 0);
+
+
+    // *** Echo quit yaSSL client server test ***
+    echo_args.argc = 2;
+    strcpy(echo_args.argv[1], "quit");
+
+    echoclient_test(&echo_args);
+    assert(echo_args.return_code == 0);
+    join_thread(thread);
+    assert(server_args.return_code == 0);
+
+
+            // input output compare
+    byte input[TaoCrypt::MD5::DIGEST_SIZE];
+    byte output[TaoCrypt::MD5::DIGEST_SIZE];
+    file_test("input", input);
+    file_test("output", output);
+    assert(memcmp(input, output, sizeof(input)) == 0);
+
+    printf("\nAll tests passed!\n");
+
+    // cleanup
+    for (int j = echo_args.argc; j >= 0; j--)
+        delete[] echo_args.argv[j];
+    delete[] echo_args.argv;
+
+    return 0;
+}
+
+
+
+void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread)
+{
+#ifdef _WIN32
+    *thread = _beginthreadex(0, 0, fun, args, 0, 0);
+#else
+    pthread_create(thread, 0, fun, args);
+#endif
+}
+
+
+void join_thread(THREAD_TYPE thread)
+{
+#ifdef _WIN32
+    int res = WaitForSingleObject(reinterpret_cast(thread), INFINITE);
+    assert(res == WAIT_OBJECT_0);
+    res = CloseHandle(reinterpret_cast(thread));
+    assert(res);
+#else
+    pthread_join(thread, 0);
+#endif
+}
diff --git a/extra/yassl/testsuite/make.bat b/extra/yassl/testsuite/make.bat
new file mode 100644
index 00000000000..d8a55b0d3af
--- /dev/null
+++ b/extra/yassl/testsuite/make.bat
@@ -0,0 +1,14 @@
+# quick and dirty build file for testing different MSDEVs
+setlocal 
+
+set myFLAGS= /I../include /I../taocrypt/include /I../mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER"
+
+cl %myFLAGS% testsuite.cpp
+cl %myFLAGS% ../examples/client/client.cpp
+cl %myFLAGS% ../examples/echoclient/echoclient.cpp
+cl %myFLAGS% ../examples/server/server.cpp
+cl %myFLAGS% ../examples/echoserver/echoserver.cpp
+cl %myFLAGS% ../taocrypt/test/test.cpp
+
+link.exe  /out:testsuite.exe ../src/yassl.lib ../taocrypt/src/taocrypt.lib testsuite.obj client.obj server.obj echoclient.obj echoserver.obj test.obj advapi32.lib Ws2_32.lib
+
diff --git a/extra/yassl/testsuite/quit b/extra/yassl/testsuite/quit
new file mode 100644
index 00000000000..3db49b3ad12
--- /dev/null
+++ b/extra/yassl/testsuite/quit
@@ -0,0 +1,2 @@
+quit
+
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
new file mode 100644
index 00000000000..79d02b63558
--- /dev/null
+++ b/extra/yassl/testsuite/test.hpp
@@ -0,0 +1,352 @@
+// test.hpp
+
+#ifndef yaSSL_TEST_HPP
+#define yaSSL_TEST_HPP
+
+#include "runtime.hpp"
+#include "openssl/ssl.h"   /* openssl compatibility test */
+#include 
+#include 
+#include 
+
+#ifdef _WIN32
+    #include 
+    #include 
+    #define SOCKET_T unsigned int
+#else
+    #include 
+    #include 
+    #include 
+    #include 
+    #include 
+    #include 
+    #include 
+    #include 
+    #include 
+    #define SOCKET_T int
+#endif /* _WIN32 */
+
+
+#if defined(__MACH__) || defined(_WIN32)
+    typedef int socklen_t;
+#endif
+
+
+// HPUX doesn't use socklent_t for third parameter to accept
+#if !defined(__hpux__)
+    typedef socklen_t* ACCEPT_THIRD_T;
+#else
+    typedef int*       ACCEPT_THIRD_T;
+#endif
+
+
+#ifndef _POSIX_THREADS
+    typedef unsigned int  THREAD_RETURN;
+    typedef unsigned long THREAD_TYPE;
+    #define YASSL_API __stdcall
+#else
+    typedef void*         THREAD_RETURN;
+    typedef pthread_t     THREAD_TYPE;
+    #define YASSL_API 
+#endif
+
+
+struct tcp_ready {
+#ifdef _POSIX_THREADS
+    pthread_mutex_t mutex_;
+    pthread_cond_t  cond_;
+    bool            ready_;   // predicate
+
+    tcp_ready() : ready_(false)
+    {
+        pthread_mutex_init(&mutex_, 0);
+        pthread_cond_init(&cond_, 0);
+    }
+
+    ~tcp_ready()
+    {
+        pthread_mutex_destroy(&mutex_);
+        pthread_cond_destroy(&cond_);
+    }
+#endif
+};    
+
+
+struct func_args {
+    int    argc;
+    char** argv;
+    int    return_code;
+    tcp_ready* signal_;
+
+    func_args(int c = 0, char** v = 0) : argc(c), argv(v) {}
+
+    void SetSignal(tcp_ready* p) { signal_ = p; }
+};
+
+typedef THREAD_RETURN YASSL_API THREAD_FUNC(void*);
+
+void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
+void join_thread(THREAD_TYPE);
+
+// yaSSL
+const char* const    yasslIP   = "127.0.0.1";
+const unsigned short yasslPort = 11111;
+
+
+// client
+const char* const cert = "../certs/client-cert.pem";
+const char* const key  = "../certs/client-key.pem";
+
+const char* const certSuite = "../../certs/client-cert.pem";
+const char* const keySuite  = "../../certs/client-key.pem";
+
+const char* const certDebug = "../../../certs/client-cert.pem";
+const char* const keyDebug  = "../../../certs/client-key.pem";
+
+
+// server
+const char* const svrCert = "../certs/server-cert.pem";
+const char* const svrKey  = "../certs/server-key.pem";
+
+const char* const svrCert2 = "../../certs/server-cert.pem";
+const char* const svrKey2  = "../../certs/server-key.pem";
+
+const char* const svrCert3 = "../../../certs/server-cert.pem";
+const char* const svrKey3  = "../../../certs/server-key.pem";
+
+
+// server dsa
+const char* const dsaCert = "../certs/dsa-cert.pem";
+const char* const dsaKey  = "../certs/dsa512.der";
+
+const char* const dsaCert2 = "../../certs/dsa-cert.pem";
+const char* const dsaKey2  = "../../certs/dsa512.der";
+
+const char* const dsaCert3 = "../../../certs/dsa-cert.pem";
+const char* const dsaKey3  = "../../../certs/dsa512.der";
+
+
+// CA 
+const char* const caCert  = "../certs/ca-cert.pem";
+const char* const caCert2 = "../../certs/ca-cert.pem";
+const char* const caCert3 = "../../../certs/ca-cert.pem";
+
+
+using namespace yaSSL;
+
+
+inline void err_sys(const char* msg)
+{
+    printf("yassl error: %s\n", msg);
+    exit(EXIT_FAILURE);
+}
+
+
+inline void store_ca(SSL_CTX* ctx)
+{
+    // To allow testing from serveral dirs
+    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
+        if (SSL_CTX_load_verify_locations(ctx, caCert2, 0) != SSL_SUCCESS)
+            if (SSL_CTX_load_verify_locations(ctx, caCert3, 0) != SSL_SUCCESS)
+                err_sys("failed to use certificate: certs/cacert.pem");
+
+    // load client CA for server verify
+    if (SSL_CTX_load_verify_locations(ctx, cert, 0) != SSL_SUCCESS)
+        if (SSL_CTX_load_verify_locations(ctx, certSuite, 0) != SSL_SUCCESS)
+            if (SSL_CTX_load_verify_locations(ctx, certDebug,0) != SSL_SUCCESS)
+                err_sys("failed to use certificate: certs/client-cert.pem");
+}
+
+
+// client
+inline void set_certs(SSL_CTX* ctx)
+{
+    store_ca(ctx);
+
+    // To allow testing from serveral dirs
+    if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)
+        != SSL_SUCCESS)
+        if (SSL_CTX_use_certificate_file(ctx, certSuite, SSL_FILETYPE_PEM)
+            != SSL_SUCCESS)
+            if (SSL_CTX_use_certificate_file(ctx, certDebug, SSL_FILETYPE_PEM)
+                != SSL_SUCCESS)
+                err_sys("failed to use certificate: certs/client-cert.pem");
+    
+    // To allow testing from several dirs
+    if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)
+         != SSL_SUCCESS) 
+         if (SSL_CTX_use_PrivateKey_file(ctx, keySuite, SSL_FILETYPE_PEM)
+            != SSL_SUCCESS) 
+                if (SSL_CTX_use_PrivateKey_file(ctx,keyDebug,SSL_FILETYPE_PEM)
+                    != SSL_SUCCESS) 
+                    err_sys("failed to use key file: certs/client-key.pem");
+}
+
+
+// server
+inline void set_serverCerts(SSL_CTX* ctx)
+{
+    store_ca(ctx);
+
+    // To allow testing from serveral dirs
+    if (SSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
+        != SSL_SUCCESS)
+        if (SSL_CTX_use_certificate_file(ctx, svrCert2, SSL_FILETYPE_PEM)
+            != SSL_SUCCESS)
+            if (SSL_CTX_use_certificate_file(ctx, svrCert3, SSL_FILETYPE_PEM)
+                != SSL_SUCCESS)
+                err_sys("failed to use certificate: certs/server-cert.pem");
+    
+    // To allow testing from several dirs
+    if (SSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
+         != SSL_SUCCESS) 
+         if (SSL_CTX_use_PrivateKey_file(ctx, svrKey2, SSL_FILETYPE_PEM)
+            != SSL_SUCCESS) 
+                if (SSL_CTX_use_PrivateKey_file(ctx, svrKey3,SSL_FILETYPE_PEM)
+                    != SSL_SUCCESS) 
+                    err_sys("failed to use key file: certs/server-key.pem");
+}
+
+
+// dsa server
+inline void set_dsaServerCerts(SSL_CTX* ctx)
+{
+    store_ca(ctx);
+
+    // To allow testing from serveral dirs
+    if (SSL_CTX_use_certificate_file(ctx, dsaCert, SSL_FILETYPE_PEM)
+        != SSL_SUCCESS)
+        if (SSL_CTX_use_certificate_file(ctx, dsaCert2, SSL_FILETYPE_PEM)
+            != SSL_SUCCESS)
+            if (SSL_CTX_use_certificate_file(ctx, dsaCert3, SSL_FILETYPE_PEM)
+                != SSL_SUCCESS)
+                err_sys("failed to use certificate: certs/dsa-cert.pem");
+    
+    // To allow testing from several dirs
+    if (SSL_CTX_use_PrivateKey_file(ctx, dsaKey, SSL_FILETYPE_ASN1)
+         != SSL_SUCCESS) 
+         if (SSL_CTX_use_PrivateKey_file(ctx, dsaKey2, SSL_FILETYPE_ASN1)
+            != SSL_SUCCESS) 
+                if (SSL_CTX_use_PrivateKey_file(ctx, dsaKey3,SSL_FILETYPE_ASN1)
+                    != SSL_SUCCESS) 
+                    err_sys("failed to use key file: certs/dsa512.der");
+}
+
+
+inline void set_args(int& argc, char**& argv, func_args& args)
+{
+    argc = args.argc;
+    argv = args.argv;
+    args.return_code = -1; // error state
+}
+
+
+inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr)
+{
+    sockfd = socket(AF_INET, SOCK_STREAM, 0);
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+
+    addr.sin_port = htons(yasslPort);
+    addr.sin_addr.s_addr = inet_addr(yasslIP);
+}
+
+
+inline void tcp_connect(SOCKET_T& sockfd)
+{
+    sockaddr_in addr;
+    tcp_socket(sockfd, addr);
+
+    if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
+        err_sys("tcp connect failed");
+}
+
+
+inline void tcp_listen(SOCKET_T& sockfd)
+{
+    sockaddr_in addr;
+    tcp_socket(sockfd, addr);
+
+    if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0)
+        err_sys("tcp bind failed");
+    if (listen(sockfd, 3) != 0)
+        err_sys("tcp listen failed");
+}
+
+
+inline void tcp_accept(SOCKET_T& sockfd, int& clientfd, func_args& args)
+{
+    tcp_listen(sockfd);
+
+    sockaddr_in client;
+    socklen_t client_len = sizeof(client);
+
+#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER)
+    // signal ready to tcp_accept
+    tcp_ready& ready = *args.signal_;
+    pthread_mutex_lock(&ready.mutex_);
+    ready.ready_ = true;
+    pthread_cond_signal(&ready.cond_);
+    pthread_mutex_unlock(&ready.mutex_);
+#endif
+
+    clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len);
+
+    if (clientfd == -1)
+        err_sys("tcp accept failed");
+}
+
+
+inline void showPeer(SSL* ssl)
+{
+    X509* peer = SSL_get_peer_certificate(ssl);
+    if (peer) {
+        char* issuer  = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0);
+        char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
+
+        printf("peer's cert info:\n");
+        printf("issuer  is: %s\n", issuer);
+        printf("subject is: %s\n", subject);
+
+        free(subject);
+        free(issuer);
+    }
+    else
+        printf("peer has no cert!\n");
+}
+
+
+
+inline DH* set_tmpDH(SSL_CTX* ctx)
+{
+    static unsigned char dh512_p[] =
+    {
+      0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+      0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+      0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+      0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+      0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+      0x47,0x74,0xE8,0x33,
+    };
+
+    static unsigned char dh512_g[] =
+    {
+      0x02,
+    };
+
+    DH* dh;
+    if ( (dh = DH_new()) ) {
+        dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0);
+        dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0);
+    }
+    if (!dh->p || !dh->g) {
+        DH_free(dh);
+        dh = 0;
+    }
+    SSL_CTX_set_tmp_dh(ctx, dh);
+    return dh;
+}
+
+
+#endif // yaSSL_TEST_HPP
+
diff --git a/extra/yassl/testsuite/testsuite.cpp b/extra/yassl/testsuite/testsuite.cpp
new file mode 100644
index 00000000000..af988432a86
--- /dev/null
+++ b/extra/yassl/testsuite/testsuite.cpp
@@ -0,0 +1,155 @@
+// testsuite.cpp
+
+#include "test.hpp"
+#include "md5.hpp"
+
+
+typedef unsigned char byte;
+
+void taocrypt_test(void*);
+void file_test(char*, byte*);
+
+void client_test(void*);
+void echoclient_test(void*);
+
+THREAD_RETURN YASSL_API server_test(void*);
+THREAD_RETURN YASSL_API echoserver_test(void*);
+
+void wait_tcp_ready(func_args&);
+
+
+
+int main(int argc, char** argv)
+{
+    func_args args(argc, argv);
+    func_args server_args(argc, argv);
+
+    // *** Crypto Test ***
+    taocrypt_test(&args);
+    assert(args.return_code == 0);
+    
+    
+    // *** Simple yaSSL client server test ***
+    tcp_ready ready;
+    server_args.SetSignal(&ready);
+
+    THREAD_TYPE serverThread;
+    start_thread(server_test, &server_args, &serverThread);
+    wait_tcp_ready(server_args);
+
+    client_test(&args);
+    assert(args.return_code == 0);
+    join_thread(serverThread);
+    assert(server_args.return_code == 0);
+    
+
+    // *** Echo input yaSSL client server test ***
+    start_thread(echoserver_test, &server_args, &serverThread);
+    wait_tcp_ready(server_args);
+    func_args echo_args;
+
+            // setup args
+    const int numArgs = 3;
+    echo_args.argc = numArgs;
+    char* myArgv[numArgs];
+
+    char argc0[32];
+    char argc1[32];
+    char argc2[32];
+
+    myArgv[0] = argc0;
+    myArgv[1] = argc1;
+    myArgv[2] = argc2;
+
+    echo_args.argv = myArgv;
+   
+    strcpy(echo_args.argv[0], "echoclient");
+    strcpy(echo_args.argv[1], "input");
+    strcpy(echo_args.argv[2], "output");
+    remove("output");
+
+            // make sure OK
+    echoclient_test(&echo_args);
+    assert(echo_args.return_code == 0);
+
+
+    // *** Echo quit yaSSL client server test ***
+    echo_args.argc = 2;
+    strcpy(echo_args.argv[1], "quit");
+
+    echoclient_test(&echo_args);
+    assert(echo_args.return_code == 0);
+    join_thread(serverThread);
+    assert(server_args.return_code == 0);
+
+
+            // input output compare
+    byte input[TaoCrypt::MD5::DIGEST_SIZE];
+    byte output[TaoCrypt::MD5::DIGEST_SIZE];
+    file_test("input", input);
+    file_test("output", output);
+    assert(memcmp(input, output, sizeof(input)) == 0);
+
+    printf("\nAll tests passed!\n");
+
+    return 0;
+}
+
+
+
+void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread)
+{
+#ifndef _POSIX_THREADS
+    *thread = _beginthreadex(0, 0, fun, args, 0, 0);
+#else
+    pthread_create(thread, 0, fun, args);
+#endif
+}
+
+
+void join_thread(THREAD_TYPE thread)
+{
+#ifndef _POSIX_THREADS
+    int res = WaitForSingleObject(reinterpret_cast(thread), INFINITE);
+    assert(res == WAIT_OBJECT_0);
+    res = CloseHandle(reinterpret_cast(thread));
+    assert(res);
+#else
+    pthread_join(thread, 0);
+#endif
+}
+
+
+
+void wait_tcp_ready(func_args& args)
+{
+#ifdef _POSIX_THREADS
+    pthread_mutex_lock(&args.signal_->mutex_);
+    
+    if (!args.signal_->ready_)
+        pthread_cond_wait(&args.signal_->cond_, &args.signal_->mutex_);
+    args.signal_->ready_ = false; // reset
+
+    pthread_mutex_unlock(&args.signal_->mutex_);
+#endif
+}
+
+
+int test_openSSL_des()
+{
+    /* test des encrypt/decrypt */
+    char data[] = "this is my data ";
+    int  dataSz = strlen(data);
+    DES_key_schedule key[3];
+    byte iv[8];
+    EVP_BytesToKey(EVP_des_ede3_cbc(), EVP_md5(), NULL, (byte*)data, dataSz, 1,
+                   (byte*)key, iv);
+
+    byte cipher[16];
+    DES_ede3_cbc_encrypt((byte*)data, cipher, dataSz, &key[0], &key[8],
+                         &key[16], &iv, true);
+    byte plain[16];
+    DES_ede3_cbc_encrypt(cipher, plain, 16, &key[0], &key[8], &key[16],
+                         &iv, false);
+    return 0;
+}
diff --git a/extra/yassl/testsuite/testsuite.dsp b/extra/yassl/testsuite/testsuite.dsp
new file mode 100644
index 00000000000..f896aa7f020
--- /dev/null
+++ b/extra/yassl/testsuite/testsuite.dsp
@@ -0,0 +1,127 @@
+# Microsoft Developer Studio Project File - Name="testsuite" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testsuite - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "testsuite.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "testsuite.mak" CFG="testsuite - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "testsuite - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "testsuite - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "testsuite - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX- /O2 /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"LIBC"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF  "$(CFG)" == "testsuite - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX- /ZI /Od /I "../taocrypt/include" /I "../include" /I "../mySTL" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "NO_MAIN_DRIVER" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"LIBCD" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "testsuite - Win32 Release"
+# Name "testsuite - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\examples\client\client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\examples\echoclient\echoclient.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\examples\echoserver\echoserver.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\examples\server\server.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\taocrypt\test\test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\testsuite.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\test.hpp
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/extra/yassl/yassl.dsp b/extra/yassl/yassl.dsp
index f51c19eebbf..dc090512743 100644
--- a/extra/yassl/yassl.dsp
+++ b/extra/yassl/yassl.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
 # PROP Intermediate_Dir "Release"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX- /O2 /I "include" /I "taocrypt\include" /I "mySTL" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /O2 /I "include" /I "taocrypt\include" /I "mySTL" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
 # PROP Intermediate_Dir "Debug"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX- /ZI /Od /I "include" /I "taocrypt\include" /I "mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "taocrypt\include" /I "mySTL" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
diff --git a/extra/yassl/yassl.dsw b/extra/yassl/yassl.dsw
index c0bba9acdce..288c88dfd5b 100644
--- a/extra/yassl/yassl.dsw
+++ b/extra/yassl/yassl.dsw
@@ -3,6 +3,21 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
 
 ###############################################################################
 
+Project: "benchmark"=.\taocrypt\benchmark\benchmark.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name taocrypt
+    End Project Dependency
+}}}
+
+###############################################################################
+
 Project: "client"=.\examples\client\client.dsp - Package Owner=<4>
 
 Package=<5>
diff --git a/include/config-win.h b/include/config-win.h
index b6fb1077cc6..6d0f40adbd3 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -382,6 +382,7 @@ inline double ulonglong2double(ulonglong value)
 #include 
 #else
 #define DEFAULT_MYSQL_HOME	"c:\\mysql"
+#define DATADIR         	"c:\\mysql\\data"
 #define PACKAGE			"mysql"
 #define DEFAULT_BASEDIR		"C:\\"
 #define SHAREDIR		"share"
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 913272b2a11..40cadad0017 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -176,7 +176,7 @@ typedef struct my_charset_handler_st
   uint    (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
   uint    (*numcells)(struct charset_info_st *, const char *b, const char *e);
   
-  /* Unicode convertion */
+  /* Unicode conversion */
   int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
 	       const unsigned char *s,const unsigned char *e);
   int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc,
@@ -186,7 +186,7 @@ typedef struct my_charset_handler_st
   int (*ctype)(struct charset_info_st *cs, int *ctype,
                const unsigned char *s, const unsigned char *e);
   
-  /* Functions for case and sort convertion */
+  /* Functions for case and sort conversion */
   void    (*caseup_str)(struct charset_info_st *, char *);
   void    (*casedn_str)(struct charset_info_st *, char *);
   uint    (*caseup)(struct charset_info_st *, char *src, uint srclen,
@@ -204,7 +204,7 @@ typedef struct my_charset_handler_st
   
   void (*fill)(struct charset_info_st *, char *to, uint len, int fill);
   
-  /* String-to-number convertion routines */
+  /* String-to-number conversion routines */
   long        (*strntol)(struct charset_info_st *, const char *s, uint l,
 			 int base, char **e, int *err);
   ulong      (*strntoul)(struct charset_info_st *, const char *s, uint l,
diff --git a/include/my_base.h b/include/my_base.h
index b9a806cc02f..e014f7c33b7 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -231,6 +231,7 @@ enum ha_base_keytype {
 #define HA_VAR_LENGTH_KEY	 8
 #define HA_NULL_PART_KEY	 64
 #define HA_USES_PARSER           16384  /* Fulltext index uses [pre]parser */
+#define HA_USES_BLOCK_SIZE	 ((uint) 32768)
 #define HA_SORT_ALLOWS_SAME      512    /* Intern bit when sorting records */
 /*
   Key has a part that can have end space.  If this is an unique key
diff --git a/include/my_global.h b/include/my_global.h
index cd0eda8aa45..0fb11738758 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -536,7 +536,7 @@ typedef unsigned short ushort;
 
 /*
   Wen using the embedded library, users might run into link problems,
-  dupicate declaration of __cxa_pure_virtual, solved by declaring it a
+  duplicate declaration of __cxa_pure_virtual, solved by declaring it a
   weak symbol.
 */
 #ifdef USE_MYSYS_NEW
diff --git a/include/my_sys.h b/include/my_sys.h
index 41851b91cbd..1540d820777 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -558,6 +558,7 @@ extern File my_open(const char *FileName,int Flags,myf MyFlags);
 extern File my_register_filename(File fd, const char *FileName,
 				 enum file_type type_of_file,
 				 uint error_message_number, myf MyFlags);
+extern void my_print_open_files(void);
 extern File my_create(const char *FileName,int CreateFlags,
 		      int AccessFlags, myf MyFlags);
 extern int my_close(File Filedes,myf MyFlags);
@@ -601,6 +602,11 @@ extern char *_my_strndup(const byte *from, uint length,
 				    const char *sFile, uint uLine,
 				    myf MyFlag);
 
+/* implemented in my_memmem.c */
+extern void *my_memmem(const void *haystack, size_t haystacklen,
+    const void *needle, size_t needlelen);
+
+
 #ifdef __WIN__
 extern int my_access(const char *path, int amode);
 extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
@@ -642,6 +648,12 @@ extern void allow_break(void);
 #define allow_break()
 #endif
 
+#ifdef EXTRA_DEBUG
+void my_print_open_files();
+#else
+#define my_print_open_files()
+#endif
+
 extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist);
 extern char *my_tmpdir(MY_TMPDIR *tmpdir);
 extern void free_tmpdir(MY_TMPDIR *tmpdir);
@@ -812,6 +824,7 @@ extern int unpackfrm(const void **, uint *, const void *);
 
 extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count);
 extern uint my_bit_log2(ulong value);
+extern uint32 my_round_up_to_next_power(uint32 v);
 extern uint my_count_bits(ulonglong v);
 extern uint my_count_bits_ushort(ushort v);
 extern void my_sleep(ulong m_seconds);
diff --git a/include/my_tree.h b/include/my_tree.h
index 14d8593b6dc..03dc9d5c829 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -84,7 +84,7 @@ TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size,
 void *tree_search(TREE *tree, void *key, void *custom_arg);
 int tree_walk(TREE *tree,tree_walk_action action,
 	      void *argument, TREE_WALK visit);
-int tree_delete(TREE *tree, void *key, void *custom_arg);
+int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg);
 void *tree_search_key(TREE *tree, const void *key, 
                       TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos,
                       enum ha_rkey_function flag, void *custom_arg);
diff --git a/include/myisam.h b/include/myisam.h
index 5116f48eeb5..db1a7bd984d 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -192,7 +192,7 @@ typedef struct st_mi_keydef		/* Key definition with open & info */
   uint16 keylength;			/* Tot length of keyparts (auto) */
   uint16 minlength;			/* min length of (packed) key (auto) */
   uint16 maxlength;			/* max length of (packed) key (auto) */
-  uint16 block_size;			/* block_size (auto) */
+  uint16 block_size_index;		/* block_size (auto) */
   uint32 version;			/* For concurrent read/write */
   uint32 ftparser_nr;                   /* distinct ftparser number */
 
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index a7b3606061f..ab5ca6e7be4 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -37,10 +37,25 @@
   be a st_mysql_plugin struct for each plugin to be declared.
 */
 
-#define mysql_declare_plugin                                          \
-int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
-int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
+
+#ifndef MYSQL_DYNAMIC_PLUGIN
+#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS)                   \
+int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION;                                  \
+int PSIZE= sizeof(struct st_mysql_plugin);                                    \
+struct st_mysql_plugin DECLS[]= {
+#else
+#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS)                   \
+int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION;         \
+int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin);          \
 struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+#endif
+
+#define mysql_declare_plugin(NAME) \
+__MYSQL_DECLARE_PLUGIN(NAME, \
+                 builtin_ ## NAME ## _plugin_interface_version, \
+                 builtin_ ## NAME ## _sizeof_struct_st_plugin, \
+                 builtin_ ## NAME ## _plugin)
+
 #define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0}}
 
 /*
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 341e6950792..9f104357f41 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -62,7 +62,8 @@ extern const char * NEAR globerrs[];	/* my_error_messages is here */
 #define EE_SYNC			27
 #define EE_UNKNOWN_COLLATION	28
 #define EE_FILENOTFOUND		29
-#define EE_ERROR_LAST           29 /*Copy last error nr.*/
+#define EE_FILE_NOT_CLOSED	30
+#define EE_ERROR_LAST           30 /* Copy last error nr */
 /* Add error numbers before EE_ERROR_LAST and change it accordingly. */
 
   /* exit codes for all MySQL programs */
diff --git a/include/violite.h b/include/violite.h
index b48f3724f5b..de2ae5386c0 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -132,6 +132,7 @@ struct st_VioSSLAcceptorFd
 		      const char *ca_file,const char *ca_path,
 		      const char *cipher);
 Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
+void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd);
 #endif /* HAVE_OPENSSL */
 
 #ifdef HAVE_SMEM
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index a869a3ccfe9..09176097be0 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -44,7 +44,10 @@ libmysqlsources =	errmsg.c get_password.c libmysql.c client.c pack.c \
 noinst_HEADERS =	embedded_priv.h emb_qcache.h
 
 sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
-	ha_heap.cc ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \
+	ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
+	ha_innodb.cc ha_berkeley.cc ha_federated.cc ha_ndbcluster.cc \
+	ha_ndbcluster_binlog.cc ha_partition.cc \
+	handler.cc sql_handler.cc \
 	hostname.cc init.cc password.c \
 	item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
 	item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
@@ -65,17 +68,12 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
 	spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
 	sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
 	parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
-        event_executor.cc event.cc event_timed.cc \
-        rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc \
-        sql_tablespace.cc \
-        rpl_injector.cc my_user.c partition_info.cc
+	event_executor.cc event.cc event_timed.cc \
+	rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
+	sql_tablespace.cc \
+	rpl_injector.cc my_user.c partition_info.cc
 
 libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
-EXTRA_libmysqld_a_SOURCES =	ha_innodb.cc ha_berkeley.cc ha_archive.cc \
-			ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
-			ha_ndbcluster_binlog.cc \
-			ha_partition.cc
-libmysqld_a_DEPENDENCIES= @mysql_se_objs@
 libmysqld_a_SOURCES=
 
 sqlstoragesources =	$(EXTRA_libmysqld_a_SOURCES)
@@ -85,15 +83,11 @@ sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
 
 # The following libraries should be included in libmysqld.a
 INC_LIB=	$(top_builddir)/regex/libregex.a \
-		$(top_builddir)/storage/myisam/libmyisam.a \
-		$(top_builddir)/storage/myisammrg/libmyisammrg.a \
-		$(top_builddir)/storage/archive/libarchive.a \
-		$(top_builddir)/storage/heap/libheap.a \
 		$(top_builddir)/mysys/libmysys.a \
 		$(top_builddir)/strings/libmystrings.a \
 		$(top_builddir)/dbug/libdbug.a \
 		$(top_builddir)/vio/libvio.a \
-		@mysql_se_libs@ \
+		@mysql_plugin_libs@ \
 		$(yassl_las)
 
 if HAVE_YASSL
diff --git a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
index 598f9746fab..0c537ee188d 100644
--- a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
+++ b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
@@ -17,3 +17,8 @@ OPTIMIZE TABLE non_existing;
 sync_slave_with_master;
 
 # End of 4.1 tests
+
+connection master;
+select * from t1;
+commit;
+drop table t1;
diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc
index 28fcf18cb16..8c277ea82a0 100644
--- a/mysql-test/include/have_ndb.inc
+++ b/mysql-test/include/have_ndb.inc
@@ -1,6 +1,15 @@
---exec test x$NDB_STATUS_OK = x1
+# Check that server is compiled and started with support for NDB
 -- require r/have_ndb.require
 disable_query_log;
 show variables like "have_ndbcluster";
 enable_query_log;
 
+# Check that NDB is installed and known to be working
+# This will disable ndb from the shell script 'mysql-test-run'
+
+-- require r/have_ndb_status_ok.require
+disable_query_log;
+eval select "$NDB_STATUS_OK" as ndb_status_ok;
+enable_query_log;
+
+
diff --git a/mysql-test/include/have_udf.inc b/mysql-test/include/have_udf.inc
index 5ed1c587385..42b9942f74d 100644
--- a/mysql-test/include/have_udf.inc
+++ b/mysql-test/include/have_udf.inc
@@ -4,11 +4,13 @@
 #
 --require r/have_udf.require
 disable_query_log;
-show variables like "have_dlopen";
+show variables like "have_dynamic_loading";
 enable_query_log;
 
 #
-# Check that the "udf_example.so" file has been created
+# Check if the variable UDF_EXAMPLE_LIB is set
 #
-
-# TODO
+--require r/have_udf_example.require
+disable_query_log;
+eval select LENGTH("$UDF_EXAMPLE_LIB") > 0 as "have_udf_example_lib";
+enable_query_log;
diff --git a/mysql-test/include/not_as_root.inc b/mysql-test/include/not_as_root.inc
new file mode 100644
index 00000000000..e0277ea593e
--- /dev/null
+++ b/mysql-test/include/not_as_root.inc
@@ -0,0 +1,4 @@
+-- require r/not_as_root.require
+disable_query_log;
+eval select "$MYSQL_TEST_ROOT" as running_as_root;
+enable_query_log;
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index 5b2fd5c6df6..b5a2e5a4a68 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -12,6 +12,7 @@ sub mtr_init_args ($);
 sub mtr_add_arg ($$@);
 sub mtr_path_exists(@);
 sub mtr_script_exists(@);
+sub mtr_file_exists(@);
 sub mtr_exe_exists(@);
 sub mtr_copy_dir($$);
 sub mtr_same_opts($$);
@@ -94,6 +95,14 @@ sub mtr_script_exists (@) {
   }
 }
 
+sub mtr_file_exists (@) {
+  foreach my $path ( @_ )
+  {
+    return $path if -e $path;
+  }
+  return "";
+}
+
 sub mtr_exe_exists (@) {
   my @path= @_;
   map {$_.= ".exe"} @path if $::glob_win32;
@@ -111,18 +120,27 @@ sub mtr_exe_exists (@) {
   }
 }
 
+
 sub mtr_copy_dir($$) {
-  my $srcdir= shift;
-  my $dstdir= shift;
+  my $from_dir= shift;
+  my $to_dir= shift;
+
+  mkpath("$to_dir");
+  opendir(DIR, "$from_dir")
+    or mtr_error("Can't find $from_dir$!");
+  for(readdir(DIR)) {
+    next if "$_" eq "." or "$_" eq "..";
+    if ( -d "$from_dir/$_" )
+    {
+      mtr_copy_dir("$from_dir/$_", "$to_dir/$_");
+      next;
+    }
+    copy("$from_dir/$_", "$to_dir/$_");
+  }
+  closedir(DIR);
 
-  # Create destination directory
-  mkpath($dstdir);
-  find(\&mtr_copy_one_file, $dstdir);
 }
 
-sub mtr_copy_one_file {
-  print $File::Find::name, "\n";
-}
 
 sub mtr_same_opts ($$) {
   my $l1= shift;
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 779be3d7081..a3fb7ec0183 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -672,12 +672,15 @@ sub mtr_mysqladmin_shutdown {
     # Shutdown time must be high as slave may be in reconnect
     mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo");
     mtr_add_arg($args, "shutdown");
+    my $path_mysqladmin_log= "$::opt_vardir/log/mysqladmin.log";
     # Start mysqladmin in paralell and wait for termination later
     my $pid= mtr_spawn($::exe_mysqladmin, $args,
-                       "", $::path_manager_log, $::path_manager_log, "",
+                       "", $path_mysqladmin_log, $path_mysqladmin_log, "",
                        { append_log_file => 1 });
     # Save the pid of the mysqladmin process
     $mysql_admin_pids{$pid}= 1;
+
+    # We don't wait for termination of mysqladmin
   }
 
   # Wait for all the started mysqladmin to exit
@@ -720,8 +723,6 @@ sub mtr_mysqladmin_shutdown {
 
   $timeout or mtr_debug("At least one server is still listening to its port");
 
-  sleep(5) if $::glob_win32;            # FIXME next startup fails if no sleep
-
   return $res;
 }
 
@@ -821,8 +822,10 @@ sub sleep_until_file_created ($$$) {
   my $pidfile= shift;
   my $timeout= shift;
   my $pid=     shift;
+  my $sleeptime= 100; # Milliseconds
+  my $loops= ($timeout * 1000) / $sleeptime;
 
-  for ( my $loop= 1; $loop <= $timeout; $loop++ )
+  for ( my $loop= 1; $loop <= $loops; $loop++ )
   {
     if ( -r $pidfile )
     {
@@ -835,16 +838,20 @@ sub sleep_until_file_created ($$$) {
       return 0;
     }
 
-    mtr_debug("Sleep 1 second waiting for creation of $pidfile");
+    mtr_debug("Sleep $sleeptime milliseconds waiting for ".
+	      "creation of $pidfile");
 
-    if ( $loop % 60 == 0 )
+    # Print extra message every 60 seconds
+    my $seconds= ($loop * $sleeptime) / 1000;
+    if ( $seconds > 1 and $seconds % 60 == 0 )
     {
-      my $left= $timeout - $loop;
-      mtr_warning("Waited $loop seconds for $pidfile to be created, " .
+      my $left= $timeout - $seconds;
+      mtr_warning("Waited $seconds seconds for $pidfile to be created, " .
                   "still waiting for $left seconds...");
     }
 
-    sleep(1);
+    # Millisceond sleep emulated with select
+    select(undef, undef, undef, ($sleeptime/1000));
   }
 
   return 0;
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index 4587c8bc385..f2da89355f7 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -157,6 +157,7 @@ sub mtr_report_stats ($) {
   my $tot_passed= 0;
   my $tot_failed= 0;
   my $tot_tests=  0;
+  my $found_problems= 0;            # Some warnings are errors...
 
   foreach my $tinfo (@$tests)
   {
@@ -214,10 +215,11 @@ sub mtr_report_stats ($) {
     }
     else
     {
-      my $found_problems= 0;            # Some warnings are errors...
-
       # We report different types of problems in order
-      foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x" )
+      foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x",
+			    "InnoDB: Warning", "missing DBUG_RETURN",
+			    "mysqld: Warning",
+			    "Attempting backtrace", "Assertion .* failed" )
       {
         foreach my $errlog ( sort glob("$::opt_vardir/log/*.err") )
         {
@@ -231,7 +233,8 @@ sub mtr_report_stats ($) {
             # Skip some non fatal warnings from the log files
             if ( /Warning:\s+Table:.* on (delete|rename)/ or
                  /Warning:\s+Setting lower_case_table_names=2/ or
-                 /Warning:\s+One can only use the --user.*root/ )
+                 /Warning:\s+One can only use the --user.*root/ or
+	         /InnoDB: Warning: we did not need to do crash recovery/)
             {
               next;                       # Skip these lines
             }
@@ -242,11 +245,11 @@ sub mtr_report_stats ($) {
             }
           }
         }
-        if ( $found_problems )
-        {
-          mtr_warning("Got errors/warnings while running tests, please examine",
-                      "\"$warnlog\" for details.");
-        }
+      }
+      if ( $found_problems )
+      {
+	mtr_warning("Got errors/warnings while running tests, please examine",
+		    "\"$warnlog\" for details.");
       }
     }
   }
@@ -266,6 +269,9 @@ sub mtr_report_stats ($) {
       }
     }
     print "\n";
+  }
+  if ( $tot_failed != 0 || $found_problems)
+  {
     mtr_error("there where failing test cases");
   }
 }
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index c8d50990c14..0087459e1dd 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -158,9 +158,9 @@ our $path_client_bindir;
 our $path_language;
 our $path_timefile;
 our $path_snapshot;
-our $path_manager_log;           # Used by mysqldadmin
 our $path_slave_load_tmpdir;     # What is this?!
 our $path_mysqltest_log;
+our $path_current_test_log;
 our $path_my_basedir;
 our $opt_vardir;                 # A path but set directly on cmd line
 our $opt_vardir_trace;           # unix formatted opt_vardir for trace files
@@ -191,6 +191,7 @@ our $exe_mysqltest;
 our $exe_slave_mysqld;
 our $exe_im;
 our $exe_my_print_defaults;
+our $lib_udf_example;
 
 our $opt_bench= 0;
 our $opt_small_bench= 0;
@@ -207,7 +208,6 @@ our $opt_sp_protocol;
 our $opt_cursor_protocol;
 our $opt_view_protocol;
 
-our $opt_current_test;
 our $opt_debug;
 our $opt_do_test;
 our @opt_cases;                  # The test cases names in argv
@@ -250,9 +250,6 @@ our $opt_ndbconnectstring;
 our $opt_ndbcluster_port_slave;
 our $opt_ndbconnectstring_slave;
 
-our $opt_no_manager;            # Does nothing now, we never use manager
-our $opt_manager_port;          # Does nothing now, we never use manager
-
 our $opt_old_master;
 
 our $opt_record;
@@ -262,6 +259,7 @@ our $opt_result_ext;
 
 our $opt_skip;
 our $opt_skip_rpl;
+our $use_slaves;
 our $opt_skip_test;
 our $opt_skip_im;
 
@@ -343,11 +341,13 @@ our @data_dir_lst;
 sub main ();
 sub initial_setup ();
 sub command_line_setup ();
+sub snapshot_setup ();
 sub executable_setup ();
 sub environment_setup ();
 sub kill_running_server ();
 sub kill_and_cleanup ();
 sub check_ssl_support ();
+sub check_running_as_root();
 sub check_ndbcluster_support ();
 sub rm_ndbcluster_tables ($);
 sub ndbcluster_install ();
@@ -357,7 +357,7 @@ sub ndbcluster_install_slave ();
 sub ndbcluster_start_slave ($);
 sub ndbcluster_stop_slave ();
 sub run_benchmarks ($);
-sub run_tests ();
+sub initialize_servers ();
 sub mysql_install_db ();
 sub install_db ($$);
 sub run_testcase ($);
@@ -388,8 +388,9 @@ sub main () {
   command_line_setup();
   executable_setup();
 
-  check_ndbcluster_support();
+  check_ndbcluster_support(); # We check whether to actually use it later
   check_ssl_support();
+  check_running_as_root();
 
   environment_setup();
   signal_setup();
@@ -404,49 +405,37 @@ sub main () {
     gprof_prepare();
   }
 
-  if ( ! $glob_use_running_server )
-  {
-    if ( $opt_start_dirty )
-    {
-      kill_running_server();
-    }
-    else
-    {
-      kill_and_cleanup();
-      mysql_install_db();
-      if ( $opt_force )
-      {
-	save_installed_db();
-      }
-    }
-  }
-
-  if ( $opt_start_dirty )
-  {
-    if ( ndbcluster_start($opt_with_ndbcluster) )
-    {
-      mtr_error("Can't start ndbcluster");
-    }
-    if ( mysqld_start('master',0,[],[],$using_ndbcluster_master) )
-    {
-      mtr_report("Servers started, exiting");
-    }
-    else
-    {
-      mtr_error("Can't start the mysqld server");
-    }
-  }
-  elsif ( $opt_bench )
+  if ( $opt_bench )
   {
+    initialize_servers();
     run_benchmarks(shift);      # Shift what? Extra arguments?!
   }
   elsif ( $opt_stress )
   {
+    initialize_servers();
     run_stress_test()
   }
   else
   {
-    run_tests();
+    # Figure out which tests we are going to run
+    my $tests= collect_test_cases($opt_suite);
+
+    # Turn off NDB and other similar options if no tests use it
+    my ($need_ndbcluster,$need_im);
+    foreach my $test (@$tests)
+    {
+      $need_ndbcluster||= $test->{ndb_test};
+      $need_im||= $test->{component_id} eq 'im';
+      $use_slaves||= $test->{slave_num};
+    }
+    $opt_with_ndbcluster= $opt_with_ndbcluster_slave= 0
+      unless $need_ndbcluster;
+    $opt_skip_im= 1 unless $need_im;
+
+    snapshot_setup();
+    initialize_servers();
+
+    run_suite($opt_suite, $tests);
   }
 
   mtr_exit(0);
@@ -589,7 +578,6 @@ sub command_line_setup () {
              'compress'                 => \$opt_compress,
              'bench'                    => \$opt_bench,
              'small-bench'              => \$opt_small_bench,
-             'no-manager'               => \$opt_no_manager, # Currently not used
 
              # Control what test suites or cases to run
              'force'                    => \$opt_force,
@@ -616,7 +604,6 @@ sub command_line_setup () {
              'slave_port=i'             => \$opt_slave_myport,
              'ndbcluster-port|ndbcluster_port=i' => \$opt_ndbcluster_port,
              'ndbcluster-port-slave=i'  => \$opt_ndbcluster_port_slave,
-             'manager-port=i'           => \$opt_manager_port, # Currently not used
              'im-port=i'                => \$im_port, # Instance Manager port.
              'im-mysqld1-port=i'        => \$im_mysqld1_port, # Port of mysqld, controlled by IM
              'im-mysqld2-port=i'        => \$im_mysqld2_port, # Port of mysqld, controlled by IM
@@ -750,11 +737,6 @@ sub command_line_setup () {
 
   $opt_tmpdir=       "$opt_vardir/tmp" unless $opt_tmpdir;
   $opt_tmpdir =~ s,/+$,,;       # Remove ending slash if any
-  # FIXME maybe not needed?
-  $path_manager_log= "$opt_vardir/log/manager.log"
-    unless $path_manager_log;
-  $opt_current_test= "$opt_vardir/log/current_test"
-    unless $opt_current_test;
 
   # --------------------------------------------------------------------------
   # Do sanity checks of command line arguments
@@ -994,22 +976,32 @@ sub command_line_setup () {
 
   $path_timefile=  "$opt_vardir/log/mysqltest-time";
   $path_mysqltest_log=  "$opt_vardir/log/mysqltest.log";
+  $path_current_test_log= "$opt_vardir/log/current_test";
 
   $path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/";
+}
+
+sub snapshot_setup () {
 
   # Make a list of all data_dirs
   @data_dir_lst = (
     $master->[0]->{'path_myddir'},
-    $master->[1]->{'path_myddir'},
-    $slave->[0]->{'path_myddir'},
-    $slave->[1]->{'path_myddir'},
-    $slave->[2]->{'path_myddir'});
+    $master->[1]->{'path_myddir'});
 
-  foreach my $instance (@{$instance_manager->{'instances'}})
+  if ($use_slaves)
   {
-    push(@data_dir_lst, $instance->{'path_datadir'});
+    push @data_dir_lst, ($slave->[0]->{'path_myddir'},
+                         $slave->[1]->{'path_myddir'},
+                         $slave->[2]->{'path_myddir'});
   }
 
+  unless ($opt_skip_im)
+  {
+    foreach my $instance (@{$instance_manager->{'instances'}})
+    {
+      push(@data_dir_lst, $instance->{'path_datadir'});
+    }
+  }
 }
 
 
@@ -1091,6 +1083,8 @@ sub executable_setup () {
                         "/usr/bin/false");
     $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/storage/ndb/tools");
     $exe_ndb_mgm=        "$glob_basedir/storage/ndb/src/mgmclient/ndb_mgm";
+    $lib_udf_example=
+      mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so");
   }
   else
   {
@@ -1188,7 +1182,7 @@ sub environment_setup () {
   # Add the path where mysqld will find udf_example.so
   # --------------------------------------------------------------------------
   $ENV{'LD_LIBRARY_PATH'}=
-    "$glob_basedir/sql/.libs" .
+    ($lib_udf_example ?  dirname($lib_udf_example) : "") .
       ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
 
 
@@ -1215,6 +1209,7 @@ sub environment_setup () {
 
   $ENV{'NDBCLUSTER_PORT'}=    $opt_ndbcluster_port;
   $ENV{'NDBCLUSTER_PORT_SLAVE'}=$opt_ndbcluster_port_slave;
+  $ENV{'NDB_STATUS_OK'}=      "YES";
 
   $ENV{'IM_PATH_PID'}=        $instance_manager->{path_pid};
   $ENV{'IM_PORT'}=            $instance_manager->{port};
@@ -1229,17 +1224,20 @@ sub environment_setup () {
   $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
 
   # We are nice and report a bit about our settings
-  print "Using MTR_BUILD_THREAD      = $ENV{MTR_BUILD_THREAD}\n";
-  print "Using MASTER_MYPORT         = $ENV{MASTER_MYPORT}\n";
-  print "Using MASTER_MYPORT1        = $ENV{MASTER_MYPORT1}\n";
-  print "Using SLAVE_MYPORT          = $ENV{SLAVE_MYPORT}\n";
-  print "Using SLAVE_MYPORT1         = $ENV{SLAVE_MYPORT1}\n";
-  print "Using SLAVE_MYPORT2         = $ENV{SLAVE_MYPORT2}\n";
-  print "Using NDBCLUSTER_PORT       = $ENV{NDBCLUSTER_PORT}\n";
-  print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n";
-  print "Using IM_PORT               = $ENV{IM_PORT}\n";
-  print "Using IM_MYSQLD1_PORT       = $ENV{IM_MYSQLD1_PORT}\n";
-  print "Using IM_MYSQLD2_PORT       = $ENV{IM_MYSQLD2_PORT}\n";
+  if (!$opt_extern)
+  {
+    print "Using MTR_BUILD_THREAD      = $ENV{MTR_BUILD_THREAD}\n";
+    print "Using MASTER_MYPORT         = $ENV{MASTER_MYPORT}\n";
+    print "Using MASTER_MYPORT1        = $ENV{MASTER_MYPORT1}\n";
+    print "Using SLAVE_MYPORT          = $ENV{SLAVE_MYPORT}\n";
+    print "Using SLAVE_MYPORT1         = $ENV{SLAVE_MYPORT1}\n";
+    print "Using SLAVE_MYPORT2         = $ENV{SLAVE_MYPORT2}\n";
+    print "Using NDBCLUSTER_PORT       = $ENV{NDBCLUSTER_PORT}\n";
+    print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n";
+    print "Using IM_PORT               = $ENV{IM_PORT}\n";
+    print "Using IM_MYSQLD1_PORT       = $ENV{IM_MYSQLD1_PORT}\n";
+    print "Using IM_MYSQLD2_PORT       = $ENV{IM_MYSQLD2_PORT}\n";
+  }
 }
 
 
@@ -1254,6 +1252,7 @@ sub signal_setup () {
   $SIG{INT}= \&handle_int_signal;
 }
 
+
 sub handle_int_signal () {
   $SIG{INT}= 'DEFAULT';         # If we get a ^C again, we die...
   mtr_warning("got INT signal, cleaning up.....");
@@ -1373,10 +1372,37 @@ sub kill_and_cleanup () {
 }
 
 
+sub  check_running_as_root () {
+  # Check if running as root
+  # i.e a file can be read regardless what mode we set it to
+  my $test_file= "test_running_as_root.txt";
+  mtr_tofile($test_file, "MySQL");
+  chmod(oct("0000"), $test_file);
+
+  my $result="";
+  if (open(FILE,"<",$test_file))
+  {
+    $result= join('', );
+    close FILE;
+  }
+
+  chmod(oct("0755"), $test_file);
+  unlink($test_file);
+
+  $ENV{'MYSQL_TEST_ROOT'}= "NO";
+  if ($result eq "MySQL")
+  {
+    mtr_warning("running this script as _root_ will cause some " .
+                "tests to be skipped");
+    $ENV{'MYSQL_TEST_ROOT'}= "YES";
+  }
+}
+
+
 
 sub check_ssl_support () {
 
-  if ($opt_skip_ssl)
+  if ($opt_skip_ssl || $opt_extern)
   {
     mtr_report("Skipping SSL");
     $opt_ssl_supported= 0;
@@ -1440,7 +1466,7 @@ sub check_ndbcluster_support () {
     return;
   }
 
-  mtr_report("Using ndbcluster, mysqld supports it");
+  mtr_report("Using ndbcluster if necessary, mysqld supports it");
   $opt_with_ndbcluster= 1;
   if ( $opt_ndbconnectstring )
   {
@@ -1471,7 +1497,6 @@ sub check_ndbcluster_support () {
   return;
 }
 
-# FIXME why is there a different start below?!
 
 sub ndbcluster_install () {
 
@@ -1501,6 +1526,7 @@ sub ndbcluster_install () {
   return 0;
 }
 
+
 sub ndbcluster_start ($) {
   my $use_ndbcluster= shift;
 
@@ -1728,12 +1754,9 @@ sub run_benchmarks ($) {
 
 # FIXME how to specify several suites to run? Comma separated list?
 
-sub run_tests () {
-  run_suite($opt_suite);
-}
 
 sub run_suite () {
-  my $suite= shift;
+  my ($suite, $tests)= @_;
 
   mtr_print_thick_line();
 
@@ -1741,8 +1764,6 @@ sub run_suite () {
 
   mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout);
 
-  my $tests= collect_test_cases($suite);
-
   mtr_report("Starting Tests in the '$suite' suite");
 
   mtr_print_header();
@@ -1784,14 +1805,37 @@ sub run_suite () {
 #
 ##############################################################################
 
+sub initialize_servers () {
+  if ( ! $glob_use_running_server )
+  {
+    if ( $opt_start_dirty )
+    {
+      kill_running_server();
+    }
+    else
+    {
+      kill_and_cleanup();
+      mysql_install_db();
+      if ( $opt_force )
+      {
+	save_installed_db();
+      }
+    }
+  }
+}
+
 sub mysql_install_db () {
 
   # FIXME not exactly true I think, needs improvements
   install_db('master', $master->[0]->{'path_myddir'});
   install_db('master', $master->[1]->{'path_myddir'});
-  install_db('slave',  $slave->[0]->{'path_myddir'});
-  install_db('slave',  $slave->[1]->{'path_myddir'});
-  install_db('slave',  $slave->[2]->{'path_myddir'});
+
+  if ( $use_slaves )
+  {
+    install_db('slave',  $slave->[0]->{'path_myddir'});
+    install_db('slave',  $slave->[1]->{'path_myddir'});
+    install_db('slave',  $slave->[2]->{'path_myddir'});
+  }
 
   if ( ! $opt_skip_im )
   {
@@ -1806,6 +1850,7 @@ sub mysql_install_db () {
       mtr_report("ndbcluster_install failed, continuing without cluster");
       $opt_with_ndbcluster= 0;
       $flag_ndb_status_ok= 0;
+      $ENV{'NDB_STATUS_OK'}= "NO";
     }
     else
     {
@@ -1815,7 +1860,7 @@ sub mysql_install_db () {
     }
   }
 
-  if ( ndbcluster_install_slave() )
+  if ( $use_slaves and ndbcluster_install_slave() )
   {
     if ( $opt_force)
     {
@@ -1845,7 +1890,7 @@ sub install_db ($$) {
   my $init_db_sql_tmp= "/tmp/init_db.sql$$";
   my $args;
 
-  mtr_report("Installing \u$type Databases");
+  mtr_report("Installing \u$type Database");
 
   open(IN, $init_db_sql)
     or mtr_error("Can't open $init_db_sql: $!");
@@ -1889,8 +1934,15 @@ sub install_db ($$) {
     mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
   }
 
+  # Log bootstrap command
+  my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
+  mtr_tofile($path_bootstrap_log,
+	     "$exe_mysqld " . join(" ", @$args) . "\n");
+
   if ( mtr_run($exe_mysqld, $args, $init_db_sql_tmp,
-               $path_manager_log, $path_manager_log, "") != 0 )
+               $path_bootstrap_log, $path_bootstrap_log,
+	       "", { append_log_file => 1 }) != 0 )
+
   {
     unlink($init_db_sql_tmp);
     mtr_error("Error executing mysqld --bootstrap\n" .
@@ -1912,15 +1964,15 @@ sub im_create_passwd_file($) {
   my $instance_manager = shift;
 
   my $pwd_file_path = $instance_manager->{'password_file'};
-  
+
   mtr_report("Creating IM password file ($pwd_file_path)");
-  
+
   open(OUT, ">", $pwd_file_path)
     or mtr_error("Can't write to $pwd_file_path: $!");
-  
+
   print OUT $instance_manager->{'admin_login'}, ":",
         $instance_manager->{'admin_sha1'}, "\n";
-  
+
   close(OUT);
 }
 
@@ -1932,7 +1984,7 @@ sub im_create_defaults_file($) {
 
   open(OUT, ">", $defaults_file)
     or mtr_error("Can't write to $defaults_file: $!");
-  
+
   print OUT <[1]->{'path_myerr'},"CURRENT_TEST: $tname\n");
   }
 
-# FIXME test cases that depend on each other, prevent this from
-# being at this location.
-#  do_before_start_master($tname,$tinfo->{'master_sh'});
+  # FIXME test cases that depend on each other, prevent this from
+  # being at this location.
+  # do_before_start_master($tname,$tinfo->{'master_sh'});
 
   # ----------------------------------------------------------------------
   # If any mysqld servers running died, we have to know
@@ -2243,10 +2295,11 @@ sub run_testcase ($) {
   }
 
   # ----------------------------------------------------------------------
-  # If --start-and-exit given, stop here to let user manually run tests
+  # If --start-and-exit or --start-dirty given, stop here to let user manually
+  # run tests
   # ----------------------------------------------------------------------
 
-  if ( $opt_start_and_exit )
+  if ( $opt_start_and_exit or $opt_start_dirty )
   {
     mtr_report("\nServers started, exiting");
     exit(0);
@@ -2312,25 +2365,6 @@ sub run_testcase ($) {
   }
 }
 
-sub copy_dir($$) {
-  my $from_dir= shift;
-  my $to_dir= shift;
-
-  mkpath("$to_dir");
-  opendir(DIR, "$from_dir")
-    or mtr_error("Can't find $from_dir$!");
-  for(readdir(DIR)) {
-    next if "$_" eq "." or "$_" eq "..";
-    if ( -d "$from_dir/$_" )
-    {
-      copy_dir("$from_dir/$_", "$to_dir/$_");
-      next;
-    }
-    copy("$from_dir/$_", "$to_dir/$_");
-  }
-  closedir(DIR);
-
-}
 
 #
 # Save a snapshot of the installed test db(s)
@@ -2344,7 +2378,7 @@ sub save_installed_db () {
   foreach my $data_dir (@data_dir_lst)
   {
     my $name= basename($data_dir);
-    copy_dir("$data_dir", "$path_snapshot/$name");
+    mtr_copy_dir("$data_dir", "$path_snapshot/$name");
   }
 }
 
@@ -2368,6 +2402,7 @@ sub save_files_before_restore($$) {
   }
 }
 
+
 #
 # Restore snapshot of the installed test db(s)
 # if the snapshot exists
@@ -2386,7 +2421,7 @@ sub restore_installed_db ($) {
       my $name= basename($data_dir);
       save_files_before_restore($test_name, $data_dir);
       rmtree("$data_dir");
-      copy_dir("$path_snapshot/$name", "$data_dir");
+      mtr_copy_dir("$path_snapshot/$name", "$data_dir");
     }
     if ($opt_with_ndbcluster)
     {
@@ -2443,9 +2478,9 @@ sub report_failure_and_restart ($) {
 #
 ##############################################################################
 
+
 # The embedded server needs the cleanup so we do some of the start work
 # but stop before actually running mysqld or anything.
-
 sub do_before_start_master ($$) {
   my $tname=       shift;
   my $init_script= shift;
@@ -2478,13 +2513,14 @@ sub do_before_start_master ($$) {
     if ( $ret != 0 )
     {
       # FIXME rewrite those scripts to return 0 if successful
-#      mtr_warning("$init_script exited with code $ret");
+      # mtr_warning("$init_script exited with code $ret");
     }
   }
   # for gcov  FIXME needed? If so we need more absolute paths
-# chdir($glob_basedir);
+  # chdir($glob_basedir);
 }
 
+
 sub do_before_start_slave ($$) {
   my $tname=       shift;
   my $init_script= shift;
@@ -2512,7 +2548,7 @@ sub do_before_start_slave ($$) {
     if ( $ret != 0 )
     {
       # FIXME rewrite those scripts to return 0 if successful
-#      mtr_warning("$init_script exited with code $ret");
+      # mtr_warning("$init_script exited with code $ret");
     }
   }
 
@@ -2522,6 +2558,7 @@ sub do_before_start_slave ($$) {
   }
 }
 
+
 sub mysqld_arguments ($$$$$$) {
   my $args=              shift;
   my $type=              shift;        # master/slave/bootstrap
@@ -2766,14 +2803,6 @@ sub mysqld_arguments ($$$$$$) {
   return $args;
 }
 
-# FIXME
-#  if ( $type eq 'master' and $glob_use_embedded_server )
-#  {
-#    # Add a -A to each argument to pass it to embedded server
-#    my @mysqltest_opt=  map {("-A",$_)} @args;
-#    $opt_extra_mysqltest_opt=  \@mysqltest_opt;
-#    return;
-#  }
 
 ##############################################################################
 #
@@ -2873,6 +2902,7 @@ sub mysqld_start ($$$$$) {
   return 0;
 }
 
+
 sub stop_masters_slaves () {
 
   print  "Ending Tests\n";
@@ -2882,7 +2912,7 @@ sub stop_masters_slaves () {
     print  "Shutting-down Instance Manager\n";
     im_stop($instance_manager);
   }
-  
+
   print  "Shutting-down MySQL daemon\n\n";
   stop_masters();
   print "Master(s) shutdown finished\n";
@@ -2890,6 +2920,7 @@ sub stop_masters_slaves () {
   print "Slave(s) shutdown finished\n";
 }
 
+
 sub stop_masters () {
 
   my @args;
@@ -2919,6 +2950,7 @@ sub stop_masters () {
   mtr_stop_mysqld_servers(\@args);
 }
 
+
 sub stop_slaves () {
   my $force= shift;
 
@@ -2973,7 +3005,7 @@ sub im_start($$) {
     mtr_add_arg($args, $opt);
   }
 
-  $instance_manager->{'pid'} = 
+  $instance_manager->{'pid'} =
     mtr_spawn(
       $exe_im,                          # path to the executable
       $args,                            # cmd-line args
@@ -2989,7 +3021,7 @@ sub im_start($$) {
     mtr_report('Could not start Instance Manager');
     return;
   }
-  
+
   # Instance Manager can be run in daemon mode. In this case, it creates
   # several processes and the parent process, created by mtr_spawn(), exits just
   # after start. So, we have to obtain Instance Manager PID from the PID file.
@@ -3007,6 +3039,7 @@ sub im_start($$) {
     mtr_get_pid_from_file($instance_manager->{'path_pid'});
 }
 
+
 sub im_stop($) {
   my $instance_manager = shift;
 
@@ -3041,12 +3074,13 @@ sub im_stop($) {
   # Kill processes.
 
   mtr_kill_processes(\@pids);
-  
+
   stop_reap_all();
 
   $instance_manager->{'pid'} = undef;
 }
 
+
 #
 # Run include/check-testcase.test
 # Before a testcase, run in record mode, save result file to var
@@ -3095,6 +3129,7 @@ sub run_check_testcase ($) {
   }
 }
 
+
 sub run_mysqltest ($) {
   my $tinfo=       shift;
 
@@ -3188,11 +3223,6 @@ sub run_mysqltest ($) {
     "--port=$master->[0]->{'path_myport'} " .
     "--socket=$master->[0]->{'path_mysock'}";
 
-
-
-  # FIXME really needing a PATH???
-  # $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}";
-
   $ENV{'MYSQL'}=                    $cmdline_mysql;
   $ENV{'MYSQL_CHECK'}=              $cmdline_mysqlcheck;
   $ENV{'MYSQL_DUMP'}=               $cmdline_mysqldump;
@@ -3205,9 +3235,11 @@ sub run_mysqltest ($) {
   $ENV{'MYSQL_CLIENT_TEST'}=        $cmdline_mysql_client_test;
   $ENV{'CHARSETSDIR'}=              $path_charsetsdir;
   $ENV{'MYSQL_MY_PRINT_DEFAULTS'}=  $exe_my_print_defaults;
+  $ENV{'UDF_EXAMPLE_LIB'}=
+    ($lib_udf_example ? basename($lib_udf_example) : "");
 
-  $ENV{'NDB_STATUS_OK'}=            $flag_ndb_status_ok;
-  $ENV{'NDB_SLAVE_STATUS_OK'}=      $flag_ndb_slave_status_ok;
+  $ENV{'NDB_STATUS_OK'}=            $flag_ndb_status_ok ? "YES" : "NO";
+  $ENV{'NDB_SLAVE_STATUS_OK'}=      $flag_ndb_slave_status_ok ? "YES" : "NO";
   $ENV{'NDB_EXTRA_TEST'}=           $opt_ndb_extra_test;
   $ENV{'NDB_MGM'}=                  $exe_ndb_mgm;
   $ENV{'NDB_BACKUP_DIR'}=           $path_ndb_data_dir;
@@ -3460,6 +3492,7 @@ sub gdb_arguments {
   $$exe= "xterm";
 }
 
+
 #
 # Modify the exe and args so that program is run in ddd
 #
@@ -3491,8 +3524,7 @@ sub ddd_arguments {
 	       "break mysql_parse\n" .
 	       "commands 1\n" .
 	       "disable 1\n" .
-	       "end\n" .
-	       "run");
+	       "end");
   }
 
   if ( $opt_manual_ddd )
@@ -3700,11 +3732,12 @@ Misc options
   comment=STR           Write STR to the output
   notimer               Don't show test case execution time
   script-debug          Debug this script itself
-  start-and-exit        Only initiate and start the "mysqld" servers, use
-                        the startup settings for the specified test case if any
-  start-dirty           Only start the "mysqld" servers without initiation
-  fast                  Don't try to cleanup from earlier runs
-  reorder               Reorder tests to get less server restarts
+  start-and-exit        Only initialize and start the servers, using the
+                        startup settings for the specified test case (if any)
+  start-dirty           Only start the servers (without initialization) for
+                        the specified test case (if any)
+  fast                  Don't try to clean up from earlier runs
+  reorder               Reorder tests to get fewer server restarts
   help                  Get this help text
   unified-diff | udiff  When presenting differences, use unified diff
 
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 7e1ae58a406..f56099f3a49 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -205,6 +205,7 @@ TOT_SKIP=0
 TOT_PASS=0
 TOT_FAIL=0
 TOT_TEST=0
+GOT_WARNINGS=0
 USERT=0
 SYST=0
 REALT=0
@@ -1072,22 +1073,21 @@ report_stats () {
     #
     $RM -f $MY_LOG_DIR/warnings $MY_LOG_DIR/warnings.tmp
     # Remove some non fatal warnings from the log files
-    $SED -e 's!Warning:  Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \
+    $SED -e 's!Warning:  Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' -e 's|InnoDB: Warning: we did not need to do crash recovery||g' \
         $MY_LOG_DIR/*.err \
         | $SED -e 's!Warning:  Table:.* on rename!!g' \
         > $MY_LOG_DIR/warnings.tmp
 
-    found_error=0
     # Find errors
-    for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN"
+    for i in "^Warning:" "^Error:" "^==.* at 0x" "InnoDB: Warning" "missing DBUG_RETURN" "mysqld: Warning" "Attempting backtrace" "Assertion .* failed"
     do
       if $GREP "$i" $MY_LOG_DIR/warnings.tmp >> $MY_LOG_DIR/warnings
       then
-        found_error=1
+        GOT_WARNINGS=1
       fi
     done
     $RM -f $MY_LOG_DIR/warnings.tmp
-    if [ $found_error = "1" ]
+    if [ $GOT_WARNINGS = "1" ]
     then
       echo "WARNING: Got errors/warnings while running tests. Please examine"
       echo "$MY_LOG_DIR/warnings for details."
@@ -2300,6 +2300,8 @@ if [ $TOT_FAIL -ne 0 ]; then
   $ECHO "mysql-test-run in $TEST_MODE mode: *** Failing the test(s):$FAILED_CASES"
   $ECHO
   exit 1
-else
-  exit 0
 fi
+if [ $GOT_WARNINGS -ne 0 ]; then
+  exit 1
+fi
+exit 0
diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh
index d55b53da2ae..74f21fdef92 100644
--- a/mysql-test/ndb/ndbcluster.sh
+++ b/mysql-test/ndb/ndbcluster.sh
@@ -264,7 +264,7 @@ done
 # test if Ndb Cluster starts properly
 
 if [ `expr $VERBOSE \> 1` = 1 ] ; then
-  echo "Waiting for started..."
+  echo "Waiting for NDB data nodes to start..."
 fi
 if ( $exec_waiter ) | grep "NDBT_ProgramExit: 0 - OK" > /dev/null 2>&1 ; then :; else
   if [ `expr $VERBOSE \> 0` = 1 ] ; then
diff --git a/mysql-test/r/analyze.result b/mysql-test/r/analyze.result
index 65c6955a959..fc267cb598d 100644
--- a/mysql-test/r/analyze.result
+++ b/mysql-test/r/analyze.result
@@ -46,4 +46,12 @@ Field_name	Min_value	Max_value	Min_length	Max_length	Empties_or_zeros	Nulls	Avg_
 execute stmt1;
 Field_name	Min_value	Max_value	Min_length	Max_length	Empties_or_zeros	Nulls	Avg_value_or_avg_length	Std	Optimal_fieldtype
 deallocate prepare stmt1;
+create temporary table t1(a int, index(a));
+insert into t1 values('1'),('2'),('3'),('4'),('5');
+analyze table t1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	OK
+show index from t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
+t1	1	a	1	a	A	5	NULL	NULL	YES	BTREE	
 drop table t1;
diff --git a/mysql-test/r/ctype_latin2_ch.result b/mysql-test/r/ctype_latin2_ch.result
index 2b3765c07c4..5b607872737 100644
--- a/mysql-test/r/ctype_latin2_ch.result
+++ b/mysql-test/r/ctype_latin2_ch.result
@@ -28,3 +28,4 @@ select * from t1 ignore index (primary) where tt like 'AA%';
 id	tt
 select * from t1 where tt like '%AA%';
 id	tt
+drop table t1;
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index ddfeeac77b5..05f1c967e77 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -186,8 +186,8 @@ a	b	a	b	a	b
 explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	SIMPLE	t2	index	PRIMARY	PRIMARY	8	NULL	3	Using where; Using index
-1	SIMPLE	t3	index	PRIMARY	PRIMARY	8	NULL	3	Using where; Using index
+1	SIMPLE	t2	ref	PRIMARY	PRIMARY	4	test.t1.a	1	Using index
+1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	8	test.t2.b,test.t1.b	1	Using index
 delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
 select * from t3;
 a	b
diff --git a/mysql-test/r/exampledb.result b/mysql-test/r/exampledb.result
index 9bfb77c1c0b..6eea24e2e1f 100644
--- a/mysql-test/r/exampledb.result
+++ b/mysql-test/r/exampledb.result
@@ -1,3 +1,5 @@
+drop database if exists events_test;
+drop database if exists events_test2;
 drop table if exists t1;
 CREATE TABLE t1 (
 Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 60022ae0d8f..e3257ce5fd0 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1, t2;
 select 1 in (1,2,3);
 1 in (1,2,3)
 1
@@ -225,3 +225,104 @@ a
 46
 DROP VIEW v1;
 DROP TABLE t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, filler char(200), key(a));
+insert into t2 select C.a*2,   'no'  from t1 A, t1 B, t1 C;
+insert into t2 select C.a*2+1, 'yes' from t1 C;
+explain 
+select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	5	NULL	12	Using where
+select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
+a	filler
+1	yes
+3	yes
+5	yes
+7	yes
+9	yes
+11	yes
+13	yes
+15	yes
+17	yes
+19	yes
+explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	5	NULL	912	Using where
+explain select * from t2 force index(a) where a <> 2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	5	NULL	912	Using where
+drop table t2;
+create table t2 (a datetime, filler char(200), key(a));
+insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
+'no'  from t1 A, t1 B, t1 C where C.a % 2 = 0;
+insert into t2 select '2006-04-25 10:00:00' + interval C.a*2+1 minute,
+'yes' from t1 C;
+explain 
+select * from t2 where a NOT IN (
+'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', 
+'2006-04-25 10:06:00', '2006-04-25 10:08:00');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	9	NULL	18	Using where
+select * from t2 where a NOT IN (
+'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', 
+'2006-04-25 10:06:00', '2006-04-25 10:08:00');
+a	filler
+2006-04-25 10:01:00	yes
+2006-04-25 10:03:00	yes
+2006-04-25 10:05:00	yes
+2006-04-25 10:07:00	yes
+2006-04-25 10:09:00	yes
+2006-04-25 10:11:00	yes
+2006-04-25 10:13:00	yes
+2006-04-25 10:15:00	yes
+2006-04-25 10:17:00	yes
+2006-04-25 10:19:00	yes
+drop table t2;
+create table t2 (a varchar(10), filler char(200), key(a));
+insert into t2 select 'foo', 'no' from t1 A, t1 B;
+insert into t2 select 'barbar', 'no' from t1 A, t1 B;
+insert into t2 select 'bazbazbaz', 'no' from t1 A, t1 B;
+insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'), 
+('barbas','1'), ('bazbazbay', '1'),('zz','1');
+explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	13	NULL	7	Using where
+drop table t2;
+create table t2 (a decimal(10,5), filler char(200), key(a));
+insert into t2 select 345.67890, 'no' from t1 A, t1 B;
+insert into t2 select 43245.34, 'no' from t1 A, t1 B;
+insert into t2 select 64224.56344, 'no' from t1 A, t1 B;
+insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'), 
+(55555,'1'), (77777, '1');
+explain
+select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	a	a	7	NULL	7	Using where
+select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
+a	filler
+0.00000	1
+22334.12300	1
+33333.00000	1
+55555.00000	1
+77777.00000	1
+drop table t2;
+create table t2 (a int, key(a), b int);
+insert into t2 values (1,1),(2,2);
+set @cnt= 1;
+set @str="update t2 set b=1 where a not in (";
+select count(*) from (
+select @str:=concat(@str, @cnt:=@cnt+1, ",") 
+from t1 A, t1 B, t1 C, t1 D) Z;
+count(*)
+10000
+set @str:=concat(@str, "10000)");
+select substr(@str, 1, 50);
+substr(@str, 1, 50)
+update t2 set b=1 where a not in (2,3,4,5,6,7,8,9,
+prepare s from @str;
+execute s;
+deallocate prepare s;
+set @str=NULL;
+drop table t2;
+drop table t1;
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 6c6e0f19e08..12d20978cf9 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -355,3 +355,17 @@ insert into mysql.user select * from t1;
 drop table t1, t2;
 drop database TESTDB;
 flush privileges;
+grant all privileges on test.* to `a@`@localhost;
+grant execute on * to `a@`@localhost;
+create table t2 (s1 int);
+insert into t2 values (1);
+drop function if exists f2;
+create function f2 () returns int begin declare v int; select s1 from t2
+into v; return v; end//
+select f2();
+f2()
+1
+drop function f2;
+drop table t2;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
+drop user `a@`@localhost;
diff --git a/mysql-test/r/have_ndb_status_ok.require b/mysql-test/r/have_ndb_status_ok.require
new file mode 100644
index 00000000000..8a82871234b
--- /dev/null
+++ b/mysql-test/r/have_ndb_status_ok.require
@@ -0,0 +1,2 @@
+ndb_status_ok
+YES
diff --git a/mysql-test/r/have_udf.require b/mysql-test/r/have_udf.require
index 6204435c17a..2d21f65e4ac 100644
--- a/mysql-test/r/have_udf.require
+++ b/mysql-test/r/have_udf.require
@@ -1,2 +1,2 @@
 Variable_name	Value
-have_dlopen	YES
+have_dynamic_loading	YES
diff --git a/mysql-test/r/have_udf_example.require b/mysql-test/r/have_udf_example.require
new file mode 100644
index 00000000000..e60fab1dbe0
--- /dev/null
+++ b/mysql-test/r/have_udf_example.require
@@ -0,0 +1,2 @@
+have_udf_example_lib
+1
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index fe918e4c3ff..a37f260ff31 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -392,3 +392,16 @@ HAVING HU.PROJ.CITY = HU.STAFF.CITY);
 EMPNUM	GRADE*1000
 E3	13000
 DROP SCHEMA HU;
+USE test;
+create table t1(f1 int);
+select f1 from t1 having max(f1)=f1;
+f1
+select f1 from t1 group by f1 having max(f1)=f1;
+f1
+set session sql_mode='ONLY_FULL_GROUP_BY';
+select f1 from t1 having max(f1)=f1;
+ERROR 42000: non-grouping field 'f1' is used in HAVING clause
+select f1 from t1 group by f1 having max(f1)=f1;
+f1
+set session sql_mode='';
+drop table t1;
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index a100266978b..7b944558a62 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -246,3 +246,13 @@ DELETE from t1 where a < 100;
 SELECT * from t1;
 a
 DROP TABLE t1;
+CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
+INSERT INTO t1 VALUES(0);
+SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
+INDEX_LENGTH
+21
+UPDATE t1 SET val=1;
+SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
+INDEX_LENGTH
+21
+DROP TABLE t1;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 5e915b5742c..898dd64b794 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -50,6 +50,7 @@ KEY_COLUMN_USAGE
 PARTITIONS
 PLUGINS
 PROCESSLIST
+REFERENTIAL_CONSTRAINTS
 ROUTINES
 SCHEMATA
 SCHEMA_PRIVILEGES
@@ -745,7 +746,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
 CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
 CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
 count(*)
-112
+113
 drop view a2, a1;
 drop table t_crashme;
 select table_schema,table_name, column_name from
@@ -759,6 +760,7 @@ information_schema	PARTITIONS	PARTITION_EXPRESSION
 information_schema	PARTITIONS	SUBPARTITION_EXPRESSION
 information_schema	PARTITIONS	PARTITION_DESCRIPTION
 information_schema	PLUGINS	PLUGIN_DESCRIPTION
+information_schema	PROCESSLIST	INFO
 information_schema	ROUTINES	ROUTINE_DEFINITION
 information_schema	ROUTINES	SQL_MODE
 information_schema	TRIGGERS	ACTION_CONDITION
@@ -832,6 +834,7 @@ COLUMN_PRIVILEGES	TABLE_NAME	select
 FILES	TABLE_NAME	select
 KEY_COLUMN_USAGE	TABLE_NAME	select
 PARTITIONS	TABLE_NAME	select
+REFERENTIAL_CONSTRAINTS	TABLE_NAME	select
 STATISTICS	TABLE_NAME	select
 TABLES	TABLE_NAME	select
 TABLE_CONSTRAINTS	TABLE_NAME	select
@@ -843,7 +846,7 @@ flush privileges;
 SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
 table_schema	count(*)
 cluster	1
-information_schema	22
+information_schema	23
 mysql	21
 create table t1 (i int, j int);
 create trigger trg1 before insert on t1 for each row
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index 584e1701a14..37537e257da 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -13,6 +13,7 @@ KEY_COLUMN_USAGE
 PARTITIONS
 PLUGINS
 PROCESSLIST
+REFERENTIAL_CONSTRAINTS
 ROUTINES
 SCHEMATA
 SCHEMA_PRIVILEGES
diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result
index fb6584673f6..9bb3185c6fb 100644
--- a/mysql-test/r/information_schema_inno.result
+++ b/mysql-test/r/information_schema_inno.result
@@ -25,3 +25,34 @@ NULL	test	PRIMARY	NULL	test	t3	id	1	NULL	NULL	NULL	NULL
 NULL	test	t3_ibfk_1	NULL	test	t3	id	1	1	test	t2	t1_id
 NULL	test	t3_ibfk_1	NULL	test	t3	t2_id	2	2	test	t2	id
 drop table t3, t2, t1;
+CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL,
+PRIMARY KEY(a1, a2)) ENGINE=INNODB;
+CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2),
+CONSTRAINT A1
+FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2)
+ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB;
+CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2),
+CONSTRAINT A2
+FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2)
+ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB;
+CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2),
+CONSTRAINT A3
+FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2)
+ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB;
+CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2),
+CONSTRAINT A4
+FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2)
+ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB;
+select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE,
+b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME,
+MATCH_OPTION, UPDATE_RULE, DELETE_RULE
+from information_schema.TABLE_CONSTRAINTS a,
+information_schema.REFERENTIAL_CONSTRAINTS b
+where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and
+a.CONSTRAINT_NAME = b.CONSTRAINT_NAME;
+CONSTRAINT_SCHEMA	TABLE_NAME	CONSTRAINT_TYPE	CONSTRAINT_NAME	UNIQUE_CONSTRAINT_SCHEMA	UNIQUE_CONSTRAINT_NAME	MATCH_OPTION	UPDATE_RULE	DELETE_RULE
+test	t2	FOREIGN KEY	A1	test	t1	NONE	CASCADE	NO ACTION
+test	t3	FOREIGN KEY	A2	test	t2	NONE	SET NULL	RESTRICT
+test	t4	FOREIGN KEY	A3	test	t3	NONE	NO ACTION	SET NULL
+test	t5	FOREIGN KEY	A4	test	t4	NONE	RESTRICT	CASCADE
+drop tables t5, t4, t3, t2, t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index f32d7ee264a..7ae87e42b8c 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -3455,3 +3455,12 @@ SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
 a
 1
 drop table t2, t1;
+create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
+ERROR HY000: The used table type doesn't support SPATIAL indexes
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+DROP TABLE t1;
diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result
new file mode 100644
index 00000000000..e0629d955ae
--- /dev/null
+++ b/mysql-test/r/myisam-system.result
@@ -0,0 +1,13 @@
+drop table if exists t1,t2;
+create table t1 (a int) engine=myisam;
+drop table if exists t1;
+Warnings:
+Error	2	Can't find file: 't1' (errno: 2)
+create table t1 (a int) engine=myisam;
+drop table t1;
+Got one of the listed errors
+create table t1 (a int) engine=myisam;
+drop table t1;
+Got one of the listed errors
+drop table t1;
+ERROR 42S02: Unknown table 't1'
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 60836408698..8976c98136b 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1344,18 +1344,6 @@ drop table t1;
 create table t1 (v varchar(65535));
 ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
 set storage_engine=MyISAM;
-create table t1 (a int) engine=myisam;
-drop table if exists t1;
-Warnings:
-Error	2	Can't find file: 't1' (errno: 2)
-create table t1 (a int) engine=myisam;
-drop table t1;
-Got one of the listed errors
-create table t1 (a int) engine=myisam;
-drop table t1;
-Got one of the listed errors
-drop table t1;
-ERROR 42S02: Unknown table 't1'
 set @save_concurrent_insert=@@concurrent_insert;
 set global concurrent_insert=1;
 create table t1 (a int);
@@ -1433,3 +1421,157 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
 create table t4 (c1 int) engine=myisam pack_keys=2;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
 drop table t1, t2, t3;
+create table t1 (a int not null, key `a` key_block_size=1024 (a));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  KEY `a` KEY_BLOCK_SIZE=1024 (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+set @@new=1;
+create table t1 (a int not null, key `a` (a) key_block_size=1024);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int not null, key `a` (a) key_block_size=2048);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=2048
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a varchar(2048), key `a` (a));
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`(1000))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`),
+  KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024
+alter table t1 key_block_size=2048;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
+  KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
+alter table t1 add c int, add key (c);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
+  KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096,
+  KEY `c` (`c`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
+alter table t1 key_block_size=0;
+alter table t1 add d int, add key (d);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  `c` int(11) DEFAULT NULL,
+  `d` int(11) DEFAULT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
+  KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096,
+  KEY `c` (`c`) KEY_BLOCK_SIZE=2048,
+  KEY `d` (`d`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`),
+  KEY `b` (`b`(1000))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
+drop table t1;
+create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
+  KEY `b` (`b`(1000))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
+drop table t1;
+create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` int(11) DEFAULT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
+  KEY `b` (`b`) KEY_BLOCK_SIZE=8192
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16384
+drop table t1;
+create table t1 (a int not null, key `a` (a) key_block_size=512);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=1024
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
+Warnings:
+Warning	1071	Specified key was too long; max key length is 1000 bytes
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` varchar(2048) DEFAULT NULL,
+  KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int not null, key `a` (a) key_block_size=1025);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  KEY `a` (`a`) KEY_BLOCK_SIZE=2048
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int not null, key key_block_size=1024 (a));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '=1024 (a))' at line 1
+set @@new=0;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index c35e1c09c5c..5da2be8da37 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -3,13 +3,14 @@ drop database if exists mysqldump_test_db;
 drop database if exists db1;
 drop database if exists db2;
 drop view if exists v1, v2, v3;
-CREATE TABLE t1(a int);
+CREATE TABLE t1(a int, key (a)) key_block_size=1024;
 INSERT INTO t1 VALUES (1), (2);
 
 
 
 	
-		
+		
+		
 	
 	
 	
diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result
index a0220a0bad8..7c687ff33a1 100644
--- a/mysql-test/r/ndb_alter_table.result
+++ b/mysql-test/r/ndb_alter_table.result
@@ -286,3 +286,45 @@ unique key tx1 (c002, c003, c004, c005)) engine=ndb;
 create index tx2 
 on t1 (c010, c011, c012, c013);
 drop table t1;
+CREATE TABLE t1 (
+auto int(5) unsigned NOT NULL auto_increment,
+string char(10),
+vstring varchar(10),
+bin binary(2),
+vbin varbinary(7),
+tiny tinyint(4) DEFAULT '0' NOT NULL ,
+short smallint(6) DEFAULT '1' NOT NULL ,
+medium mediumint(8) DEFAULT '0' NOT NULL,
+long_int int(11) DEFAULT '0' NOT NULL,
+longlong bigint(13) DEFAULT '0' NOT NULL,
+real_float float(13,1) DEFAULT 0.0 NOT NULL,
+real_double double(16,4),
+real_decimal decimal(16,4),
+utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+ulong int(11) unsigned DEFAULT '0' NOT NULL,
+ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+bits bit(3),
+options enum('zero','one','two','three','four') not null,
+flags set('zero','one','two','three','four') not null,
+date_field date,
+year_field year,
+time_field time,
+date_time datetime,
+time_stamp timestamp,
+PRIMARY KEY (auto)
+) engine=ndb;
+CREATE TEMPORARY TABLE ndb_show_tables (id INT, type VARCHAR(20), state VARCHAR(20), logging VARCHAR(20), _database VARCHAR(255), _schema VARCHAR(20), name VARCHAR(255));
+LOAD DATA INFILE 'tmp.dat' INTO TABLE ndb_show_tables;
+set @t1_id = (select id from ndb_show_tables where name like '%t1%');
+truncate ndb_show_tables;
+alter table t1 change tiny new_tiny tinyint(4) DEFAULT '0' NOT NULL;
+create index i1 on t1(medium);
+alter table t1 add index i2(long_int);
+drop index i1 on t1;
+LOAD DATA INFILE 'tmp.dat' INTO TABLE ndb_show_tables;
+select 'no_copy' from ndb_show_tables where id = @t1_id and name like '%t1%';
+no_copy
+no_copy
+DROP TABLE t1, ndb_show_tables;
diff --git a/mysql-test/r/ndb_alter_table_row.result b/mysql-test/r/ndb_alter_table3.result
similarity index 100%
rename from mysql-test/r/ndb_alter_table_row.result
rename to mysql-test/r/ndb_alter_table3.result
diff --git a/mysql-test/r/ndb_alter_table_stm.result b/mysql-test/r/ndb_alter_table_stm.result
deleted file mode 100644
index 7cb7b990e2c..00000000000
--- a/mysql-test/r/ndb_alter_table_stm.result
+++ /dev/null
@@ -1,29 +0,0 @@
-DROP TABLE IF EXISTS t1;
-create table t1 ( a int primary key, b varchar(10), c varchar(10), index (b) )
-engine=ndb;
-insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three');
-create index c on t1(c);
-select * from t1 where c = 'two';
-a	b	c
-2	two	two
-alter table t1 drop index c;
-select * from t1 where c = 'two';
-select * from t1 where c = 'two';
-a	b	c
-2	two	two
-drop table t1;
-create table t3 (a int primary key) engine=ndbcluster;
-begin;
-insert into t3 values (1);
-alter table t3 rename t4;
-delete from t3;
-insert into t3 values (1);
-commit;
-select * from t3;
-ERROR HY000: Can't lock file (errno: 155)
-select * from t4;
-a
-1
-drop table t4;
-show tables;
-Tables_in_test
diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result
index 4a1f5f587df..9477caf97ab 100644
--- a/mysql-test/r/ndb_basic.result
+++ b/mysql-test/r/ndb_basic.result
@@ -6,6 +6,13 @@ attr1 INT NOT NULL,
 attr2 INT,
 attr3 VARCHAR(10)
 ) ENGINE=ndbcluster;
+drop table t1;
+CREATE TABLE t1 (
+pk1 INT NOT NULL PRIMARY KEY,
+attr1 INT NOT NULL,
+attr2 INT,
+attr3 VARCHAR(10)
+) ENGINE=ndbcluster;
 SHOW INDEX FROM t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
 t1	0	PRIMARY	1	pk1	A	0	NULL	NULL		BTREE	
diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result
index 9c76d46f4f0..7a781ae3bde 100644
--- a/mysql-test/r/ndb_blob.result
+++ b/mysql-test/r/ndb_blob.result
@@ -481,14 +481,22 @@ msg text NOT NULL
 insert into t1 (msg) values(
 'Tries to validate (8 byte length + inline bytes) as UTF8 :(
 Fast fix: removed validation for Text.  It is not yet indexable
-so bad data will not crash kernel.
-Proper fix: Set inline bytes to multiple of mbmaxlen and
-validate it (after the 8 byte length).');
+so bad data will not crash kernel.');
 select * from t1;
 id	msg
 1	Tries to validate (8 byte length + inline bytes) as UTF8 :(
 Fast fix: removed validation for Text.  It is not yet indexable
 so bad data will not crash kernel.
-Proper fix: Set inline bytes to multiple of mbmaxlen and
-validate it (after the 8 byte length).
+drop table t1;
+create table t1 (
+a int primary key not null auto_increment,
+b text
+) engine=ndbcluster;
+select count(*) from t1;
+count(*)
+500
+truncate t1;
+select count(*) from t1;
+count(*)
+0
 drop table t1;
diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result
index d2a8a91828c..c364b8f1b5d 100644
--- a/mysql-test/r/ndb_config.result
+++ b/mysql-test/r/ndb_config.result
@@ -8,4 +8,3 @@ ndbd,1,localhost,52428800,26214400 ndbd,2,localhost,52428800,36700160 ndbd,3,loc
 ndbd,1,localhost ndbd,2,localhost ndbd,3,localhost ndbd,4,localhost ndb_mgmd,5,localhost mysqld,6, mysqld,7, mysqld,8, mysqld,9, mysqld,10,
 ndbd,2,localhost ndbd,3,localhost ndbd,4,localhost ndbd,5,localhost ndb_mgmd,6,localhost mysqld,1, mysqld,7, mysqld,8, mysqld,9, mysqld,10,
 ndbd,3,localhost ndbd,4,localhost ndbd,5,localhost ndbd,6,localhost ndb_mgmd,1,localhost ndb_mgmd,2,localhost mysqld,11, mysqld,12, mysqld,13, mysqld,14, mysqld,15,
-shm,3,4,35,3 shm,3,5,35,3 shm,3,6,35,3 shm,4,5,35,4 shm,4,6,35,4 shm,5,6,35,5 tcp,11,3,55,3 tcp,11,4,55,4 tcp,11,5,55,5 tcp,11,6,55,6 tcp,12,3,55,3 tcp,12,4,55,4 tcp,12,5,55,5 tcp,12,6,55,6 tcp,13,3,55,3 tcp,13,4,55,4 tcp,13,5,55,5 tcp,13,6,55,6 tcp,14,3,55,3 tcp,14,4,55,4 tcp,14,5,55,5 tcp,14,6,55,6 tcp,15,3,55,3 tcp,15,4,55,4 tcp,15,5,55,5 tcp,15,6,55,6 tcp,1,3,55,1 tcp,1,4,55,1 tcp,1,5,55,1 tcp,1,6,55,1 tcp,2,3,55,2 tcp,2,4,55,2 tcp,2,5,55,2 tcp,2,6,55,2
diff --git a/mysql-test/r/ndb_config2.result b/mysql-test/r/ndb_config2.result
new file mode 100644
index 00000000000..cfd012933c4
--- /dev/null
+++ b/mysql-test/r/ndb_config2.result
@@ -0,0 +1 @@
+shm,3,4,35,3 shm,3,5,35,3 shm,3,6,35,3 shm,4,5,35,4 shm,4,6,35,4 shm,5,6,35,5 tcp,11,3,55,3 tcp,11,4,55,4 tcp,11,5,55,5 tcp,11,6,55,6 tcp,12,3,55,3 tcp,12,4,55,4 tcp,12,5,55,5 tcp,12,6,55,6 tcp,13,3,55,3 tcp,13,4,55,4 tcp,13,5,55,5 tcp,13,6,55,6 tcp,14,3,55,3 tcp,14,4,55,4 tcp,14,5,55,5 tcp,14,6,55,6 tcp,15,3,55,3 tcp,15,4,55,4 tcp,15,5,55,5 tcp,15,6,55,6 tcp,1,3,55,1 tcp,1,4,55,1 tcp,1,5,55,1 tcp,1,6,55,1 tcp,2,3,55,2 tcp,2,4,55,2 tcp,2,5,55,2 tcp,2,6,55,2
diff --git a/mysql-test/r/ndb_dd_basic.result b/mysql-test/r/ndb_dd_basic.result
index d5ac5071a8e..ee1b717e6f1 100644
--- a/mysql-test/r/ndb_dd_basic.result
+++ b/mysql-test/r/ndb_dd_basic.result
@@ -5,20 +5,20 @@ INITIAL_SIZE 16M
 UNDO_BUFFER_SIZE = 1M
 ENGINE=MYISAM;
 Warnings:
-Error	1539	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
+Error	1465	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
 ALTER LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile02.dat'
 INITIAL_SIZE = 4M 
 ENGINE=XYZ;
 Warnings:
 Error	1266	Using storage engine MyISAM for table 'lg1'
-Error	1539	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
+Error	1465	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
 CREATE TABLESPACE ts1
 ADD DATAFILE 'datafile.dat'
 USE LOGFILE GROUP lg1
 INITIAL_SIZE 12M;
 Warnings:
-Error	1539	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
+Error	1465	Table storage engine 'MyISAM' does not support the create option 'TABLESPACE or LOGFILE GROUP'
 set storage_engine=ndb;
 CREATE LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile.dat'
diff --git a/mysql-test/r/ndb_dd_ddl.result b/mysql-test/r/ndb_dd_ddl.result
index 39dceef1573..47b95214024 100644
--- a/mysql-test/r/ndb_dd_ddl.result
+++ b/mysql-test/r/ndb_dd_ddl.result
@@ -16,7 +16,7 @@ ERROR HY000: Failed to create LOGFILE GROUP
 SHOW WARNINGS;
 Level	Code	Message
 Error	1296	Got error 1514 'Currently there is a limit of one logfile group' from NDB
-Error	1507	Failed to create LOGFILE GROUP
+Error	1515	Failed to create LOGFILE GROUP
 CREATE LOGFILE GROUP lg1
 ADD UNDOFILE 'undofile.dat'
 INITIAL_SIZE 16M
diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result
index 229339d603e..497ad973e8b 100644
--- a/mysql-test/r/ndb_index_unique.result
+++ b/mysql-test/r/ndb_index_unique.result
@@ -45,6 +45,8 @@ a	b	c
 8	2	3
 alter table t1 drop index ib;
 insert into t1 values(1, 2, 3);
+create unique index ib on t1(b);
+ERROR 23000: Can't write, because of unique constraint, to table 't1'
 drop table t1;
 CREATE TABLE t1 (
 a int unsigned NOT NULL PRIMARY KEY,
diff --git a/mysql-test/r/ndb_multi_row.result b/mysql-test/r/ndb_multi_row.result
index 64b151d42a9..cf5a76d6f01 100644
--- a/mysql-test/r/ndb_multi_row.result
+++ b/mysql-test/r/ndb_multi_row.result
@@ -62,4 +62,6 @@ t4
 drop table t1, t2, t3, t4;
 drop table if exists t1, t3, t4;
 Warnings:
+Error	155	Table 'test.t1' doesn't exist
 Error	155	Table 'test.t3' doesn't exist
+Error	155	Table 'test.t4' doesn't exist
diff --git a/mysql-test/r/not_as_root.require b/mysql-test/r/not_as_root.require
new file mode 100644
index 00000000000..d9ea5244efc
--- /dev/null
+++ b/mysql-test/r/not_as_root.require
@@ -0,0 +1,2 @@
+running_as_root
+NO
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 9a7ae446707..68fc6ff7f5f 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -278,3 +278,45 @@ field('str1', null, 'STR1') as c05,
 c01	c02	c03	c04	c05	c08	c09
 str	str	0	1	2	1	1
 set names latin1;
+create table bug19145a (e enum('a','b','c')          default 'b' , s set('x', 'y', 'z')          default 'y' ) engine=MyISAM;
+create table bug19145b (e enum('a','b','c')          default null, s set('x', 'y', 'z')          default null) engine=MyISAM;
+create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM;
+create table bug19145setnotnulldefaultnull (e enum('a','b','c')          default null, s set('x', 'y', 'z') not null default null) engine=MyISAM;
+ERROR 42000: Invalid default value for 's'
+create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z')          default null) engine=MyISAM;
+ERROR 42000: Invalid default value for 'e'
+alter table bug19145a alter column e set default null;
+alter table bug19145a alter column s set default null;
+alter table bug19145a add column (i int);
+alter table bug19145b alter column e set default null;
+alter table bug19145b alter column s set default null;
+alter table bug19145b add column (i int);
+alter table bug19145c alter column e set default null;
+ERROR 42000: Invalid default value for 'e'
+alter table bug19145c alter column s set default null;
+ERROR 42000: Invalid default value for 's'
+alter table bug19145c add column (i int);
+show create table bug19145a;
+Table	Create Table
+bug19145a	CREATE TABLE `bug19145a` (
+  `e` enum('a','b','c') DEFAULT NULL,
+  `s` set('x','y','z') DEFAULT NULL,
+  `i` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table bug19145b;
+Table	Create Table
+bug19145b	CREATE TABLE `bug19145b` (
+  `e` enum('a','b','c') DEFAULT NULL,
+  `s` set('x','y','z') DEFAULT NULL,
+  `i` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table bug19145c;
+Table	Create Table
+bug19145c	CREATE TABLE `bug19145c` (
+  `e` enum('a','b','c') NOT NULL DEFAULT 'b',
+  `s` set('x','y','z') NOT NULL DEFAULT 'y',
+  `i` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table bug19145a;
+drop table bug19145b;
+drop table bug19145c;
diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result
index 77f2d5495a9..91382619b6c 100644
--- a/mysql-test/r/openssl_1.result
+++ b/mysql-test/r/openssl_1.result
@@ -38,7 +38,6 @@ f1
 5
 delete from t1;
 ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1'
-delete from mysql.user where user='ssl_user%';
-delete from mysql.db where user='ssl_user%';
-flush privileges;
+drop user ssl_user1@localhost, ssl_user2@localhost,
+ssl_user3@localhost, ssl_user4@localhost;
 drop table t1;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 3de7ab61e73..06443cde01d 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1056,3 +1056,104 @@ a	b
 1	9
 3	7
 drop table t1;
+create table t1 (a int);
+create table t2 like t1;
+create table t3 like t2;
+prepare stmt from "repair table t1";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+prepare stmt from "optimize table t1";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	Table is already up to date
+prepare stmt from "analyze table t1";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+prepare stmt from "repair table t1, t2, t3";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t2	repair	status	OK
+test.t3	repair	status	OK
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t2	repair	status	OK
+test.t3	repair	status	OK
+prepare stmt from "optimize table t1, t2, t3";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+test.t2	optimize	status	OK
+test.t3	optimize	status	OK
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	Table is already up to date
+test.t2	optimize	status	Table is already up to date
+test.t3	optimize	status	Table is already up to date
+prepare stmt from "analyze table t1, t2, t3";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+test.t2	analyze	status	Table is already up to date
+test.t3	analyze	status	Table is already up to date
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+test.t2	analyze	status	Table is already up to date
+test.t3	analyze	status	Table is already up to date
+prepare stmt from "repair table t1, t4, t3";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t4	repair	error	Table 'test.t4' doesn't exist
+test.t3	repair	status	OK
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t4	repair	error	Table 'test.t4' doesn't exist
+test.t3	repair	status	OK
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+prepare stmt from "optimize table t1, t3, t4";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+test.t3	optimize	status	OK
+test.t4	optimize	error	Table 'test.t4' doesn't exist
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	Table is already up to date
+test.t3	optimize	status	Table is already up to date
+test.t4	optimize	error	Table 'test.t4' doesn't exist
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+prepare stmt from "analyze table t4, t1";
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t4	analyze	error	Table 'test.t4' doesn't exist
+test.t1	analyze	status	Table is already up to date
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+execute stmt;
+Table	Op	Msg_type	Msg_text
+test.t4	analyze	error	Table 'test.t4' doesn't exist
+test.t1	analyze	status	Table is already up to date
+Warnings:
+Error	1146	Table 'test.t4' doesn't exist
+deallocate prepare stmt;
diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result
index c0d7fe502af..c849c25d646 100644
--- a/mysql-test/r/ps_11bugs.result
+++ b/mysql-test/r/ps_11bugs.result
@@ -116,3 +116,17 @@ execute st_1676 using @arg0, @arg1, @arg2;
 cola	colb	cold
 aaaa	yyyy	R
 drop table t1, t2;
+create table t1 (a int primary key);
+insert into t1 values (1);
+explain select * from t1 where 3 in (select (1+1) union select 1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+2	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
+3	DEPENDENT UNION	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
+NULL	UNION RESULT		ALL	NULL	NULL	NULL	NULL	NULL	
+select * from t1 where 3 in (select (1+1) union select 1);
+a
+prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)';
+execute st_18492;
+a
+drop table t1;
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index 22d59c7bd8f..d0b773dfe34 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -410,13 +410,10 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
 prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
 execute stmt1 ;
 prepare stmt1 from ' optimize table t1 ' ;
-ERROR HY000: This command is not supported in the prepared statement protocol yet
 prepare stmt1 from ' analyze table t1 ' ;
-ERROR HY000: This command is not supported in the prepared statement protocol yet
 prepare stmt1 from ' checksum table t1 ' ;
 ERROR HY000: This command is not supported in the prepared statement protocol yet
 prepare stmt1 from ' repair table t1 ' ;
-ERROR HY000: This command is not supported in the prepared statement protocol yet
 prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
 ERROR HY000: This command is not supported in the prepared statement protocol yet
 prepare stmt1 from ' handler t1 open ';
diff --git a/mysql-test/r/rpl_deadlock_innodb.result b/mysql-test/r/rpl_deadlock_innodb.result
index 1bcd59ce234..b9a23950ed8 100644
--- a/mysql-test/r/rpl_deadlock_innodb.result
+++ b/mysql-test/r/rpl_deadlock_innodb.result
@@ -50,7 +50,7 @@ Master_User	root
 Master_Port	MASTER_MYPORT
 Connect_Retry	1
 Master_Log_File	master-bin.000001
-Read_Master_Log_Pos	18911
+Read_Master_Log_Pos	#
 Relay_Log_File	#
 Relay_Log_Pos	#
 Relay_Master_Log_File	master-bin.000001
@@ -59,13 +59,13 @@ Slave_SQL_Running	Yes
 Replicate_Do_DB	
 Replicate_Ignore_DB	
 Replicate_Do_Table	
-Replicate_Ignore_Table	
+Replicate_Ignore_Table	#
 Replicate_Wild_Do_Table	
 Replicate_Wild_Ignore_Table	
 Last_Errno	0
 Last_Error	
 Skip_Counter	0
-Exec_Master_Log_Pos	18911
+Exec_Master_Log_Pos	#
 Relay_Log_Space	#
 Until_Condition	None
 Until_Log_File	
@@ -99,7 +99,7 @@ Master_User	root
 Master_Port	MASTER_MYPORT
 Connect_Retry	1
 Master_Log_File	master-bin.000001
-Read_Master_Log_Pos	18911
+Read_Master_Log_Pos	#
 Relay_Log_File	#
 Relay_Log_Pos	#
 Relay_Master_Log_File	master-bin.000001
@@ -108,13 +108,13 @@ Slave_SQL_Running	Yes
 Replicate_Do_DB	
 Replicate_Ignore_DB	
 Replicate_Do_Table	
-Replicate_Ignore_Table	
+Replicate_Ignore_Table	#
 Replicate_Wild_Do_Table	
 Replicate_Wild_Ignore_Table	
 Last_Errno	0
 Last_Error	
 Skip_Counter	0
-Exec_Master_Log_Pos	18911
+Exec_Master_Log_Pos	#
 Relay_Log_Space	#
 Until_Condition	None
 Until_Log_File	
@@ -150,7 +150,7 @@ Master_User	root
 Master_Port	MASTER_MYPORT
 Connect_Retry	1
 Master_Log_File	master-bin.000001
-Read_Master_Log_Pos	18911
+Read_Master_Log_Pos	#
 Relay_Log_File	#
 Relay_Log_Pos	#
 Relay_Master_Log_File	master-bin.000001
@@ -159,13 +159,13 @@ Slave_SQL_Running	Yes
 Replicate_Do_DB	
 Replicate_Ignore_DB	
 Replicate_Do_Table	
-Replicate_Ignore_Table	
+Replicate_Ignore_Table	#
 Replicate_Wild_Do_Table	
 Replicate_Wild_Ignore_Table	
 Last_Errno	0
 Last_Error	
 Skip_Counter	0
-Exec_Master_Log_Pos	18911
+Exec_Master_Log_Pos	#
 Relay_Log_Space	#
 Until_Condition	None
 Until_Log_File	
diff --git a/mysql-test/r/rpl_failed_optimize.result b/mysql-test/r/rpl_failed_optimize.result
index fd711f89222..ec0b3856ae7 100644
--- a/mysql-test/r/rpl_failed_optimize.result
+++ b/mysql-test/r/rpl_failed_optimize.result
@@ -18,3 +18,8 @@ Table	Op	Msg_type	Msg_text
 test.non_existing	optimize	error	Table 'test.non_existing' doesn't exist
 Warnings:
 Error	1146	Table 'test.non_existing' doesn't exist
+select * from t1;
+a
+1
+commit;
+drop table t1;
diff --git a/mysql-test/r/rpl_loaddatalocal.result b/mysql-test/r/rpl_loaddatalocal.result
index 20e56a62133..bb1b0610aa8 100644
--- a/mysql-test/r/rpl_loaddatalocal.result
+++ b/mysql-test/r/rpl_loaddatalocal.result
@@ -18,12 +18,12 @@ select * into outfile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_out
 drop table t1;
 create table t1(a int primary key);
 load data local infile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1;
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 a
 1
 2
 3
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 a
 1
 2
diff --git a/mysql-test/r/rpl_openssl.result b/mysql-test/r/rpl_openssl.result
index be9ab29d8b7..4fe02088632 100644
--- a/mysql-test/r/rpl_openssl.result
+++ b/mysql-test/r/rpl_openssl.result
@@ -24,6 +24,7 @@ Slave_IO_State	Master_Host	Master_User	Master_Port	Connect_Retry	Master_Log_File
 stop slave;
 change master to master_user='root',master_password='', master_ssl=0;
 start slave;
+drop user replssl@localhost;
 drop table t1;
 show slave status;
 Slave_IO_State	Master_Host	Master_User	Master_Port	Connect_Retry	Master_Log_File	Read_Master_Log_Pos	Relay_Log_File	Relay_Log_Pos	Relay_Master_Log_File	Slave_IO_Running	Slave_SQL_Running	Replicate_Do_DB	Replicate_Ignore_DB	Replicate_Do_Table	Replicate_Ignore_Table	Replicate_Wild_Do_Table	Replicate_Wild_Ignore_Table	Last_Errno	Last_Error	Skip_Counter	Exec_Master_Log_Pos	Relay_Log_Space	Until_Condition	Until_Log_File	Until_Log_Pos	Master_SSL_Allowed	Master_SSL_CA_File	Master_SSL_CA_Path	Master_SSL_Cert	Master_SSL_Cipher	Master_SSL_Key	Seconds_Behind_Master
diff --git a/mysql-test/r/rpl_sp_effects.result b/mysql-test/r/rpl_sp_effects.result
index bf8128d9385..26455b65beb 100644
--- a/mysql-test/r/rpl_sp_effects.result
+++ b/mysql-test/r/rpl_sp_effects.result
@@ -19,24 +19,30 @@ set spv=spv+1;
 end while;
 end//
 call p1();
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
+a
+1
+2
+3
+4
+5
+SELECT * FROM t1 ORDER BY a;
 a
 1
 2
 3
 4
 5
-delete from t1;
 create procedure p2()
 begin
 declare a int default 4;
 create table t2 as select a;
 end//
 call p2();
-select * from t2;
+SELECT * FROM t2 ORDER BY a;
 a
 4
-select * from t2;
+SELECT * FROM t2 ORDER BY a;
 a
 4
 drop procedure p1;
@@ -61,43 +67,58 @@ end//
 call p1(f1(1), f1(2));
 yes
 yes
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 a
 1
+1
 2
+2
+3
+4
+5
 5
 6
 7
 8
 create table t2(a int);
 insert into t2 values (10),(11);
-select a,f1(a) from t2;
+SELECT a,f1(a) FROM t2 ORDER BY a;
 a	f1(a)
 10	11
 11	12
 insert into t2 select f1(3);
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 master:	a
 master:	1
+master:	1
 master:	2
+master:	2
+master:	3
+master:	3
+master:	4
+master:	5
 master:	5
 master:	6
 master:	7
 master:	8
 master:	10
 master:	11
-master:	3
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 slave:	a
 slave:	1
+slave:	1
 slave:	2
+slave:	2
+slave:	3
+slave:	3
+slave:	4
+slave:	5
 slave:	5
 slave:	6
 slave:	7
 slave:	8
 slave:	10
 slave:	11
-slave:	3
 drop procedure p1;
 delete from t1;
 delete from t2;
@@ -108,11 +129,11 @@ select * from v1;
 f1(a)
 2
 3
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 master:	a
 master:	1
 master:	2
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 slave:	a
 slave:	1
 slave:	2
@@ -123,10 +144,10 @@ set @xx=123;
 execute s1 using @xx;
 f1(?)
 124
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 master:	a
 master:	123
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 slave:	a
 slave:	123
 delete from t1;
@@ -141,18 +162,18 @@ set spv= spv - 10;
 end while;
 end//
 call p1(15);
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 master:	a
-master:	15
-master:	15
 master:	6
 master:	6
-select 'slave:',a from t1;
+master:	15
+master:	15
+SELECT 'slave:',a FROM t1 ORDER BY a;
 slave:	a
-slave:	15
-slave:	15
 slave:	6
 slave:	6
+slave:	15
+slave:	15
 drop procedure p1;
 drop function f1;
 drop table t1,t2;
@@ -187,26 +208,26 @@ f1()
 0
 set @x=30;
 call p1();
-select 'master', a from t1;
+SELECT 'master', a FROM t1 ORDER BY a;
 master	a
-master	20
 master	10
 master	11
-master	100
-master	101
+master	20
 master	30
 master	31
+master	100
+master	101
 master	101
 master	102
-select 'slave', a from t1;
+SELECT 'slave', a FROM t1 ORDER BY a;
 slave	a
-slave	20
 slave	10
 slave	11
-slave	100
-slave	101
+slave	20
 slave	30
 slave	31
+slave	100
+slave	101
 slave	101
 slave	102
 drop table t1;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 9b9f67efeb5..e9092fc8a69 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3390,3 +3390,24 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t2	const	PRIMARY	PRIMARY	4	const	1	
 1	SIMPLE	t1	range	PRIMARY	PRIMARY	4	NULL	2	Using where
 DROP TABLE t1,t2;
+CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
+INSERT t1 SET i = 0;
+UPDATE t1 SET i = -1;
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = CAST(i - 1 AS SIGNED);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+0
+UPDATE t1 SET i = i - 1;
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+SELECT * FROM t1;
+i
+255
+DROP TABLE t1;
diff --git a/mysql-test/r/sp-dynamic.result b/mysql-test/r/sp-dynamic.result
index c00b09f90e1..d9d5706cded 100644
--- a/mysql-test/r/sp-dynamic.result
+++ b/mysql-test/r/sp-dynamic.result
@@ -286,12 +286,12 @@ id	stmt_text	status
 1	select 1	supported
 2	flush tables	not supported
 3	handler t1 open as ha	not supported
-4	analyze table t1	not supported
+4	analyze table t1	supported
 5	check table t1	not supported
 6	checksum table t1	not supported
 7	check table t1	not supported
-8	optimize table t1	not supported
-9	repair table t1	not supported
+8	optimize table t1	supported
+9	repair table t1	supported
 10	describe extended select * from t1	supported
 11	help help	not supported
 12	show databases	supported
diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result
index a1e78cd9d7e..af4f1c16c56 100644
--- a/mysql-test/r/sp-security.result
+++ b/mysql-test/r/sp-security.result
@@ -322,6 +322,7 @@ Warnings:
 Warning	1541	The syntax 'SHOW INNODB STATUS' is deprecated and will be removed in MySQL 5.2. Please use 'SHOW ENGINE INNODB STATUS' instead.
 GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost;
 DROP DATABASE db_bug7787;
+drop user user_bug7787@localhost;
 use test;
 
 ---> connection: root
diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
index d434f5c32ce..c8cafe5ace1 100644
--- a/mysql-test/r/sp_notembedded.result
+++ b/mysql-test/r/sp_notembedded.result
@@ -1,3 +1,4 @@
+drop table if exists t1,t3;
 drop procedure if exists bug4902|
 create procedure bug4902()
 begin
@@ -204,3 +205,4 @@ drop procedure bug10100pv|
 drop procedure bug10100pd|
 drop procedure bug10100pc|
 drop view v1|
+drop table t3|
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 37823c66de9..0a464d055c2 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -744,7 +744,7 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 3	DEPENDENT UNION	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
 NULL	UNION RESULT		ALL	NULL	NULL	NULL	NULL	NULL	
 Warnings:
-Note	1003	select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id`,(select 1 AS `Not_used` having ((`test`.`t2`.`id`) = (1)) union select 1 AS `Not_used` having ((`test`.`t2`.`id`) = (3))))
+Note	1003	select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id`,(select 1 AS `1` having ((`test`.`t2`.`id`) = (1)) union select 3 AS `3` having ((`test`.`t2`.`id`) = (3))))
 SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
 id
 SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -1354,10 +1354,10 @@ a
 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t2	index	NULL	a	5	NULL	4	Using where; Using index
-2	DEPENDENT SUBQUERY	t3	index	a	a	5	NULL	3	Using index
-2	DEPENDENT SUBQUERY	t1	ref	a	a	10	func,test.t3.a	1167	Using where; Using index
+2	DEPENDENT SUBQUERY	t1	ref	a	a	5	func	1001	Using where; Using index
+2	DEPENDENT SUBQUERY	t3	index	a	a	5	NULL	3	Using where; Using index
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and ((`test`.`t2`.`a`) = `test`.`t1`.`a`))))
 insert into t1 values (3,31);
 select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 a
diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result
index 5cc4150e374..fe9e971af2f 100644
--- a/mysql-test/r/timezone2.result
+++ b/mysql-test/r/timezone2.result
@@ -1,4 +1,5 @@
 drop table if exists t1, t2;
+drop function if exists f1;
 create table t1 (ts timestamp);
 set time_zone='+00:00';
 select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
@@ -268,3 +269,17 @@ select * from t1;
 convert_tz(NULL, NULL, NULL)
 NULL
 drop table t1;
+create table t1 (ldt datetime, udt datetime);
+create function f1(i datetime) returns datetime
+return convert_tz(i, 'UTC', 'Europe/Moscow');
+create trigger t1_bi before insert on t1 for each row
+set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
+insert into t1 (ldt) values ('2006-04-19 16:30:00');
+select * from t1;
+ldt	udt
+2006-04-19 16:30:00	2006-04-19 12:30:00
+select ldt, f1(udt) as ldt2 from t1;
+ldt	ldt2
+2006-04-19 16:30:00	2006-04-19 16:30:00
+drop table t1;
+drop function f1;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index a0c4e212d58..5d5ea9511ba 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -949,7 +949,7 @@ insert into t1 values
 create function f2() returns int return (select max(b) from t2);
 insert into t2 select a, f2() from t1;
 load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
-drop tables t1, t2;
+drop table t1, t2;
 drop function f1;
 drop function f2;
 create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index 1b5f59c038a..01aa8539262 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -1,15 +1,15 @@
 drop table if exists t1;
-CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
-CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
-CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME 'udf_example.so';
+CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
 ERROR HY000: Can't find symbol 'myfunc_nonexist' in library
-CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
-CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so";
-CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
+CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION sequence RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION lookup RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
 CREATE FUNCTION reverse_lookup
-RETURNS STRING SONAME 'udf_example.so';
+RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
 CREATE AGGREGATE FUNCTION avgcost
-RETURNS REAL SONAME 'udf_example.so';
+RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
 select myfunc_double();
 ERROR HY000: myfunc_double must have at least one argument
 select myfunc_double(1);
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 8f2b89c18fd..9c3fdf0d8d2 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -215,9 +215,6 @@ select @@version;
 select @@global.version;
 @@global.version
 #
-select @@session.VERSION;
-@@session.VERSION
-#
 set @first_var= NULL;
 create table t1 select @first_var;
 show create table t1;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index ec8a715de1b..43b32782c63 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -275,7 +275,7 @@ ERROR HY000: Variable 'autocommit' is a SESSION variable and can't be used with
 select @@global.timestamp;
 ERROR HY000: Variable 'timestamp' is a SESSION variable
 set @@version='';
-ERROR HY000: Unknown system variable 'version'
+ERROR HY000: Variable 'version' is a read only variable
 set @@concurrent_insert=1;
 ERROR HY000: Variable 'concurrent_insert' is a GLOBAL variable and should be set with SET GLOBAL
 set @@global.sql_auto_is_null=1;
@@ -384,6 +384,7 @@ select @@sql_max_join_size,@@max_join_size;
 set sql_quote_show_create=1;
 set sql_safe_updates=1;
 set sql_select_limit=1;
+set sql_select_limit=default;
 set sql_warnings=1;
 set global table_open_cache=100;
 set storage_engine=myisam;
@@ -584,3 +585,31 @@ set @@global.character_set_filesystem=default;
 select @@global.character_set_filesystem;
 @@global.character_set_filesystem
 binary
+set @old_sql_big_selects = @@sql_big_selects;
+set @@sql_big_selects = 1;
+show variables like 'sql_big_selects';
+Variable_name	Value
+sql_big_selects	ON
+set @@sql_big_selects = @old_sql_big_selects;
+set @@sql_notes = 0, @@sql_warnings = 0;
+show variables like 'sql_notes';
+Variable_name	Value
+sql_notes	OFF
+show variables like 'sql_warnings';
+Variable_name	Value
+sql_warnings	OFF
+set @@sql_notes = 1, @@sql_warnings = 1;
+show variables like 'sql_notes';
+Variable_name	Value
+sql_notes	ON
+show variables like 'sql_warnings';
+Variable_name	Value
+sql_warnings	ON
+select @@system_time_zone;
+@@system_time_zone
+#
+select @@version, @@version_comment, @@version_compile_machine,
+@@version_compile_os;
+@@version	@@version_comment	@@version_compile_machine	@@version_compile_os
+#	#	#	#
+End of 5.0 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 91ee6716723..c5446ac314e 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2606,7 +2606,7 @@ create view v2 as select * from v1;
 drop table t1;
 rename table v2 to t1;
 select * from v1;
-ERROR HY000: `test`.`v1` contain view recursion
+ERROR HY000: `test`.`v1` contains view recursion
 drop view t1, v1;
 create table t1 (a int);
 create function f1() returns int
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 61dd1390a6a..06dc2f3d78a 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -665,3 +665,12 @@ CALL p2();
 EXTRACTVALUE(p,'/Ñ/r')
 A
 DROP PROCEDURE p2;
+select extractValue('','count(ns:element)');
+extractValue('','count(ns:element)')
+1
+select extractValue('a','/ns:element');
+extractValue('a','/ns:element')
+a
+select extractValue('a','/ns:element/@xmlns:ns');
+extractValue('a','/ns:element/@xmlns:ns')
+myns
diff --git a/mysql-test/t/analyze.test b/mysql-test/t/analyze.test
index a8fd0a4283e..1801a4a440f 100644
--- a/mysql-test/t/analyze.test
+++ b/mysql-test/t/analyze.test
@@ -61,6 +61,14 @@ prepare stmt1 from "SELECT * FROM t1 PROCEDURE ANALYSE()";
 execute stmt1;
 execute stmt1;
 deallocate prepare stmt1;
+
+#
+# bug#15225 (ANALYZE temporary has no effect)
+#
+create temporary table t1(a int, index(a));
+insert into t1 values('1'),('2'),('3'),('4'),('5');
+analyze table t1;
+show index from t1;
 drop table t1;
 
 # End of 4.1 tests
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index 533da542855..b733a23f398 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -47,7 +47,7 @@ select cast('1a' as signed);
 select cast('' as signed);
 
 #
-# Character set convertion
+# Character set conversion
 #
 set names binary;
 select cast(_latin1'test' as char character set latin2);
diff --git a/mysql-test/t/ctype_latin2_ch.test b/mysql-test/t/ctype_latin2_ch.test
index 626d83fa17d..3925d02659d 100644
--- a/mysql-test/t/ctype_latin2_ch.test
+++ b/mysql-test/t/ctype_latin2_ch.test
@@ -28,3 +28,5 @@ select * from t1 ignore index (primary) where tt like 'AA%';
 select * from t1 where tt like '%AA%';
 
 # End of 4.1 tests
+
+drop table t1;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index cac42cd60a3..288d060b2b5 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -15,26 +15,26 @@ events                   : BUG#17619 2006-02-21 andrey  Race conditions
 events_scheduling        : BUG#19170 2006-04-26 andrey  Test case of 19170 fails on some platforms. Has to be checked.
 ndb_autodiscover         : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
 ndb_autodiscover2        : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
+ndb_binlog_discover      : BUG#19395 2006-04-28 tomas/knielsen mysqld does not always detect cluster shutdown
 #ndb_cache2               : BUG#18597 2006-03-28 brian simultaneous drop table and ndb statistics update triggers node failure
 #ndb_cache_multi2         : BUG#18597 2006-04-10 kent  simultaneous drop table and ndb statistics update triggers node failure
+ndb_load                 : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed
 partition_03ndb          : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
 ps_7ndb                  : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open
-rpl_deadlock_innodb      : BUG#16920 2006-04-12 kent    fails in show slave status (randomly)
 rpl_ndb_2innodb          : BUG#19227 2006-04-20 pekka pk delete apparently not replicated
 rpl_ndb_2myisam          : BUG#19227 2006-04-20 pekka pk delete apparently not replicated
 rpl_ndb_auto_inc         : BUG#17086 2006-02-16 jmiller CR: auto_increment_increment and auto_increment_offset produce duplicate key er
-rpl_ndb_dd_partitions    : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on solaris
+rpl_ndb_commit_afterflush : BUG#19328 2006-05-04 tomas Slave timeout with COM_REGISTER_SLAVE error causing stop
+rpl_ndb_dd_partitions    : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
 rpl_ndb_ddl              : BUG#18946 result file needs update + test needs to checked
 rpl_ndb_innodb2ndb       : BUG#17400 2006-04-19 tomas Cluster Replication: delete & update of rows in table without pk fails on slave.
 rpl_ndb_log              : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ
 rpl_ndb_myisam2ndb       : BUG#17400 2006-04-19 tomas Cluster Replication: delete & update of rows in table without pk fails on slave.
 rpl_switch_stm_row_mixed : BUG#18590 2006-03-28 brian
 rpl_row_blob_innodb      : BUG#18980 2006-04-10 kent    Test fails randomly
-rpl_row_func003		 : BUG#19074 2006-13-04 andrei  test failed
+rpl_row_func003 	 : BUG#19074 2006-13-04 andrei  test failed
 rpl_row_inexist_tbl      : BUG#18948 2006-03-09 mats    Disabled since patch makes this test wait forever
 rpl_sp                   : BUG#16456 2006-02-16 jmiller
-rpl_until                : BUG#15886 2006-02-16 jmiller Unstable test case
-mysqldump                : BUG#18078 2006-03-10 lars
 udf                      : BUG#18564 2006-03-27 ian     (Permission by Brian)
 
 # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test
index f80297682b7..fbcd4924d56 100644
--- a/mysql-test/t/events.test
+++ b/mysql-test/t/events.test
@@ -320,9 +320,9 @@ drop event one_event;
 create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
 select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
 drop event e_26;
---error 1504
+--error ER_WRONG_VALUE
 create event e_26 on schedule at NULL disabled do set @a = 5;
---error 1504
+--error ER_WRONG_VALUE
 create event e_26 on schedule at 'definitely not a datetime' disabled do set @a = 5;
 
 set names utf8;
diff --git a/mysql-test/t/exampledb.test b/mysql-test/t/exampledb.test
index 946d25325dc..fbb2a18f344 100644
--- a/mysql-test/t/exampledb.test
+++ b/mysql-test/t/exampledb.test
@@ -5,6 +5,10 @@
 -- source include/have_exampledb.inc
 
 --disable_warnings
+# Clean up if event's test fails
+drop database if exists events_test;
+drop database if exists events_test2;
+
 drop table if exists t1;
 --enable_warnings
 
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 0472968f918..351d1fc2c92 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -1,6 +1,6 @@
 # Initialise
 --disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2;
 --enable_warnings
 #
 # test of IN (NULL)
@@ -128,3 +128,95 @@ SELECT * FROM v1;
 
 DROP VIEW v1;
 DROP TABLE t1;
+
+# BUG#15872: Excessive memory consumption of range analysis of NOT IN
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 
+create table t2 (a int, filler char(200), key(a));
+
+insert into t2 select C.a*2,   'no'  from t1 A, t1 B, t1 C;
+insert into t2 select C.a*2+1, 'yes' from t1 C;
+
+explain 
+select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
+select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
+
+explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
+explain select * from t2 force index(a) where a <> 2;
+
+drop table t2;
+
+#
+# Repeat the test for DATETIME
+#
+create table t2 (a datetime, filler char(200), key(a));
+
+insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
+               'no'  from t1 A, t1 B, t1 C where C.a % 2 = 0;
+
+insert into t2 select '2006-04-25 10:00:00' + interval C.a*2+1 minute,
+               'yes' from t1 C;
+
+explain 
+select * from t2 where a NOT IN (
+  '2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', 
+  '2006-04-25 10:06:00', '2006-04-25 10:08:00');
+select * from t2 where a NOT IN (
+  '2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00', 
+  '2006-04-25 10:06:00', '2006-04-25 10:08:00');
+drop table t2;
+
+#
+# Repeat the test for CHAR(N)
+#
+create table t2 (a varchar(10), filler char(200), key(a));
+
+insert into t2 select 'foo', 'no' from t1 A, t1 B;
+insert into t2 select 'barbar', 'no' from t1 A, t1 B;
+insert into t2 select 'bazbazbaz', 'no' from t1 A, t1 B;
+
+insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'), 
+  ('barbas','1'), ('bazbazbay', '1'),('zz','1');
+
+explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
+
+drop table t2;
+
+#
+# Repeat for DECIMAL
+#
+create table t2 (a decimal(10,5), filler char(200), key(a));
+
+insert into t2 select 345.67890, 'no' from t1 A, t1 B;
+insert into t2 select 43245.34, 'no' from t1 A, t1 B;
+insert into t2 select 64224.56344, 'no' from t1 A, t1 B;
+
+insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'), 
+  (55555,'1'), (77777, '1');
+
+explain
+select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
+select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
+
+drop table t2;
+
+# Try a very big IN-list
+create table t2 (a int, key(a), b int);
+insert into t2 values (1,1),(2,2);
+
+set @cnt= 1; 
+set @str="update t2 set b=1 where a not in (";
+select count(*) from (
+  select @str:=concat(@str, @cnt:=@cnt+1, ",") 
+  from t1 A, t1 B, t1 C, t1 D) Z;
+
+set @str:=concat(@str, "10000)");
+select substr(@str, 1, 50);
+prepare s from @str;
+execute s;
+deallocate prepare s;
+set @str=NULL;
+
+drop table t2;
+drop table t1;
+
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index ce1d0fb2271..b3e2d2f7998 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -462,3 +462,29 @@ drop table t1, t2;
 drop database TESTDB;
 flush privileges;
 
+#
+# BUG#13310 incorrect user parsing by SP
+#
+
+grant all privileges on test.* to `a@`@localhost;
+grant execute on * to `a@`@localhost;
+connect (bug13310,localhost,'a@',,test);
+connection bug13310;
+create table t2 (s1 int);
+insert into t2 values (1);
+--disable_warnings
+drop function if exists f2;
+--enable_warnings
+delimiter //;
+create function f2 () returns int begin declare v int; select s1 from t2
+into v; return v; end//
+delimiter ;//
+select f2();
+
+drop function f2;
+drop table t2;
+disconnect bug13310;
+
+connection default;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost;
+drop user `a@`@localhost;
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index 9b21e544657..41266cc6d32 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -393,3 +393,16 @@ SELECT EMPNUM, GRADE*1000
                            HAVING HU.PROJ.CITY = HU.STAFF.CITY);
 
 DROP SCHEMA HU;
+USE test;
+#
+# Bug#18739: non-standard HAVING extension was allowed in strict ANSI sql mode.
+#
+create table t1(f1 int);
+select f1 from t1 having max(f1)=f1;
+select f1 from t1 group by f1 having max(f1)=f1;
+set session sql_mode='ONLY_FULL_GROUP_BY';
+--error ER_NON_GROUPING_FIELD_USED
+select f1 from t1 having max(f1)=f1;
+select f1 from t1 group by f1 having max(f1)=f1;
+set session sql_mode='';
+drop table t1;
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index 5e493c2643b..f1b9d290885 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -164,4 +164,16 @@ DELETE from t1 where a < 100;
 SELECT * from t1;
 DROP TABLE t1;
 
+#
+# BUG#18160 - Memory-/HEAP Table endless growing indexes
+#
+CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
+INSERT INTO t1 VALUES(0);
+--replace_result 37 21
+SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
+UPDATE t1 SET val=1;
+--replace_result 37 21
+SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
+DROP TABLE t1;
+
 # End of 4.1 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index c6dd9c7226d..b7151b03ae1 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1,10 +1,13 @@
 # This test  uses grants, which can't get tested for embedded server
 -- source include/not_embedded.inc
 
-# check that CSV engine was compiled in, as the result of the test
-# depends on the presence of the log tables (which are CSV-based).
+# check that CSV engine was compiled in, as the result of the test depends
+# on the presence of the log tables (which are CSV-based).
 --source include/have_csv.inc
 
+# This test uses chmod, can't be run with root permissions
+-- source include/not_as_root.inc
+
 # Test for information_schema.schemata &
 # show databases
 
diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test
index 9cd64a54ad9..195bf57a880 100644
--- a/mysql-test/t/information_schema_inno.test
+++ b/mysql-test/t/information_schema_inno.test
@@ -21,3 +21,35 @@ select * from information_schema.KEY_COLUMN_USAGE where
 TABLE_SCHEMA= "test";
 
 drop table t3, t2, t1;
+
+#
+# Test for REFERENTIAL_CONSTRAINTS table
+#
+CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL,
+                PRIMARY KEY(a1, a2)) ENGINE=INNODB;
+CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2),
+                CONSTRAINT A1
+                FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2)
+                ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB;
+CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2),
+		CONSTRAINT A2
+		FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2)
+		ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB;
+CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2),
+                CONSTRAINT A3
+                FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2)
+                ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB;
+CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2),
+                CONSTRAINT A4
+                FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2)
+                ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB;
+		
+		
+select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE,
+       b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME,
+       MATCH_OPTION, UPDATE_RULE, DELETE_RULE
+from information_schema.TABLE_CONSTRAINTS a,
+     information_schema.REFERENTIAL_CONSTRAINTS b
+where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and
+a.CONSTRAINT_NAME = b.CONSTRAINT_NAME;
+drop tables t5, t4, t3, t2, t1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index cadb611714c..92e060eed92 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -2494,3 +2494,19 @@ SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
 SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
 
 drop table t2, t1;
+
+#
+# Bug #15680 (SPATIAL key in innodb)
+#
+--error ER_TABLE_CANT_HANDLE_SPKEYS
+create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
+
+#
+# Test optimize on table with open transaction
+#
+
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index 3b412d9e793..048da802d02 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -63,10 +63,10 @@ flush logs;
 # check locking of the log tables
 #
 
---error 1533
+--error ER_CANT_WRITE_LOCK_LOG_TABLE
 lock tables mysql.general_log WRITE;
 
---error 1533
+--error ER_CANT_WRITE_LOCK_LOG_TABLE
 lock tables mysql.slow_log WRITE;
 
 #
@@ -75,10 +75,10 @@ lock tables mysql.slow_log WRITE;
 # tables are always opened and locked by the logger.
 #
 
---error 1534
+--error ER_CANT_READ_LOCK_LOG_TABLE
 lock tables mysql.general_log READ;
 
---error 1534
+--error ER_CANT_READ_LOCK_LOG_TABLE
 lock tables mysql.slow_log READ;
 
 #
diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test
new file mode 100644
index 00000000000..43fbaabf698
--- /dev/null
+++ b/mysql-test/t/myisam-system.test
@@ -0,0 +1,21 @@
+#
+# Test how DROP TABLE works if the index or data file doesn't exists
+
+# Initialise
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+create table t1 (a int) engine=myisam;
+system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
+drop table if exists t1;
+create table t1 (a int) engine=myisam;
+system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
+--error 1051,6
+drop table t1;
+create table t1 (a int) engine=myisam;
+system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
+--error 1105,6,29
+drop table t1;
+--error 1051
+drop table t1;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 15533ca00e6..87a00399c23 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -726,23 +726,6 @@ create table t1 (v varchar(65535));
 
 eval set storage_engine=$default;
 
-#
-# Test how DROP TABLE works if the index or data file doesn't exists
-
-create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
-drop table if exists t1;
-create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
---error 1051,6
-drop table t1;
-create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
---error 1105,6,29
-drop table t1;
---error 1051
-drop table t1;
-
 #
 # Test concurrent insert
 # First with static record length
@@ -824,3 +807,72 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
 create table t4 (c1 int) engine=myisam pack_keys=2;
 drop table t1, t2, t3;
 
+#
+# Test of key_block_size
+#
+
+# Old format, to be obsolete in 5.3
+create table t1 (a int not null, key `a` key_block_size=1024 (a));
+show create table t1;
+drop table t1;
+
+set @@new=1;
+
+create table t1 (a int not null, key `a` (a) key_block_size=1024);
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, key `a` (a) key_block_size=2048);
+show create table t1;
+drop table t1;
+
+create table t1 (a varchar(2048), key `a` (a));
+show create table t1;
+drop table t1;
+
+create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
+show create table t1;
+alter table t1 key_block_size=2048;
+show create table t1;
+alter table t1 add c int, add key (c);
+show create table t1;
+alter table t1 key_block_size=0;
+alter table t1 add d int, add key (d);
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
+show create table t1;
+drop table t1;
+
+
+# Test limits and errors of key_block_size
+
+create table t1 (a int not null, key `a` (a) key_block_size=512);
+show create table t1;
+drop table t1;
+
+create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
+show create table t1;
+drop table t1;
+
+create table t1 (a int not null, key `a` (a) key_block_size=1025);
+show create table t1;
+drop table t1;
+
+--error 1064
+create table t1 (a int not null, key key_block_size=1024 (a));
+
+set @@new=0;
diff --git a/mysql-test/t/mysql_client_test-master.opt b/mysql-test/t/mysql_client_test-master.opt
new file mode 100644
index 00000000000..3711946168d
--- /dev/null
+++ b/mysql-test/t/mysql_client_test-master.opt
@@ -0,0 +1 @@
+--log --log-output=FILE 
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 5ba7838bb81..c5c3f88d8c8 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -11,7 +11,7 @@ drop view if exists v1, v2, v3;
 
 # XML output
 
-CREATE TABLE t1(a int);
+CREATE TABLE t1(a int, key (a)) key_block_size=1024;
 INSERT INTO t1 VALUES (1), (2);
 --exec $MYSQL_DUMP --skip-create --skip-comments -X test t1
 DROP TABLE t1;
@@ -1174,8 +1174,8 @@ create database first;
 use first;
 set time_zone = 'UTC';
 
-## prove one works
-create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;
+## prove one works (with spaces and tabs on the end)
+create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;    	 	
 show events;
 show create event ee1;
 --exec $MYSQL_DUMP --events first > $MYSQLTEST_VARDIR/tmp/bug16853-1.sql
@@ -1187,10 +1187,10 @@ use second;
 show events;
 show create event ee1;
 
-## prove three works
+## prove three works (with spaces and tabs on the end)
 # start with one from the previous restore
-create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
-create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
+create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;	      
+create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;    		
 show events;
 --exec $MYSQL_DUMP --events second > $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
 drop database second;
diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test
index a12ac20a259..29deea4aa0d 100644
--- a/mysql-test/t/ndb_alter_table.test
+++ b/mysql-test/t/ndb_alter_table.test
@@ -327,3 +327,59 @@ drop table t1;
 
 # End of 4.1 tests
 
+# On-line alter table
+
+
+CREATE TABLE t1 (
+  auto int(5) unsigned NOT NULL auto_increment,
+  string char(10),
+  vstring varchar(10),
+  bin binary(2),
+  vbin varbinary(7),
+  tiny tinyint(4) DEFAULT '0' NOT NULL ,
+  short smallint(6) DEFAULT '1' NOT NULL ,
+  medium mediumint(8) DEFAULT '0' NOT NULL,
+  long_int int(11) DEFAULT '0' NOT NULL,
+  longlong bigint(13) DEFAULT '0' NOT NULL,
+  real_float float(13,1) DEFAULT 0.0 NOT NULL,
+  real_double double(16,4),
+  real_decimal decimal(16,4),
+  utiny tinyint(3) unsigned DEFAULT '0' NOT NULL,
+  ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL,
+  umedium mediumint(8) unsigned DEFAULT '0' NOT NULL,
+  ulong int(11) unsigned DEFAULT '0' NOT NULL,
+  ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL,
+  bits bit(3),
+  options enum('zero','one','two','three','four') not null,
+  flags set('zero','one','two','three','four') not null,
+  date_field date,
+  year_field year,
+  time_field time,
+  date_time datetime,
+  time_stamp timestamp,
+  PRIMARY KEY (auto)
+) engine=ndb;
+                                                                                                   
+CREATE TEMPORARY TABLE ndb_show_tables (id INT, type VARCHAR(20), state VARCHAR(20), logging VARCHAR(20), _database VARCHAR(255), _schema VARCHAR(20), name VARCHAR(255));
+
+--disable_warnings
+--exec $NDB_TOOLS_DIR/ndb_show_tables --p > $MYSQLTEST_VARDIR/master-data/test/tmp.dat
+LOAD DATA INFILE 'tmp.dat' INTO TABLE ndb_show_tables;
+--enable_warnings
+
+set @t1_id = (select id from ndb_show_tables where name like '%t1%');
+truncate ndb_show_tables;
+
+alter table t1 change tiny new_tiny tinyint(4) DEFAULT '0' NOT NULL;
+create index i1 on t1(medium);
+alter table t1 add index i2(long_int);
+drop index i1 on t1;
+
+--disable_warnings
+--exec $NDB_TOOLS_DIR/ndb_show_tables --p > $MYSQLTEST_VARDIR/master-data/test/tmp.dat
+LOAD DATA INFILE 'tmp.dat' INTO TABLE ndb_show_tables;
+--enable_warnings
+
+select 'no_copy' from ndb_show_tables where id = @t1_id and name like '%t1%';
+
+DROP TABLE t1, ndb_show_tables;
diff --git a/mysql-test/t/ndb_alter_table_row.test b/mysql-test/t/ndb_alter_table3.test
similarity index 96%
rename from mysql-test/t/ndb_alter_table_row.test
rename to mysql-test/t/ndb_alter_table3.test
index 9c834e0dd20..a5fe613adcf 100644
--- a/mysql-test/t/ndb_alter_table_row.test
+++ b/mysql-test/t/ndb_alter_table3.test
@@ -1,7 +1,6 @@
 -- source include/have_ndb.inc
 -- source include/have_multi_ndb.inc
 -- source include/not_embedded.inc
--- source include/have_binlog_format_row.inc
 
 --disable_warnings
 DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/t/ndb_alter_table_stm.test b/mysql-test/t/ndb_alter_table_stm.test
deleted file mode 100644
index bf162dd0d50..00000000000
--- a/mysql-test/t/ndb_alter_table_stm.test
+++ /dev/null
@@ -1,55 +0,0 @@
--- source include/have_ndb.inc
--- source include/have_multi_ndb.inc
--- source include/not_embedded.inc
--- source include/have_binlog_format_statement.inc
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
-connection server1;
-create table t1 ( a int primary key, b varchar(10), c varchar(10), index (b) )
-engine=ndb;
-insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three');
-create index c on t1(c); 
-connection server2;
-select * from t1 where c = 'two';
-connection server1;
-alter table t1 drop index c;
-connection server2;
-
---disable_result_log
---error 0,1412
-select * from t1 where c = 'two';
---enable_result_log
-
-select * from t1 where c = 'two';
-connection server1;
-drop table t1;
-
-connection server1;
-create table t3 (a int primary key) engine=ndbcluster;
-
-connection server2;
-begin;
-insert into t3 values (1);
-
-connection server1;
-alter table t3 rename t4;
-
-connection server2;
-# with rbr the below will not work as the "alter" event
-# explicitly invalidates the dictionary cache.
-# This should work as transaction is ongoing...
-delete from t3;
-insert into t3 values (1);
-commit; 
-
-# This should fail as its a new transaction
---error 1015
-select * from t3;
-select * from t4;
-drop table t4;
-show tables;
-connection server1;
-
diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test
index ab62e3dd13a..edf74ab1df9 100644
--- a/mysql-test/t/ndb_basic.test
+++ b/mysql-test/t/ndb_basic.test
@@ -6,6 +6,18 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
 drop database if exists mysqltest;
 --enable_warnings
 
+# workaround for bug#16445
+# remove to reproduce bug and run tests from ndb start
+# and with ndb_autodiscover disabled. Fails on Linux 50 % of the times
+
+CREATE TABLE t1 (
+  pk1 INT NOT NULL PRIMARY KEY,
+  attr1 INT NOT NULL,
+  attr2 INT,
+  attr3 VARCHAR(10)
+) ENGINE=ndbcluster;
+drop table t1;
+
 #
 # Basic test to show that the NDB 
 # table handler is working
diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test
index f80b7f71281..bf82a793049 100644
--- a/mysql-test/t/ndb_blob.test
+++ b/mysql-test/t/ndb_blob.test
@@ -403,10 +403,29 @@ create table t1 (
 insert into t1 (msg) values(
 'Tries to validate (8 byte length + inline bytes) as UTF8 :(
 Fast fix: removed validation for Text.  It is not yet indexable
-so bad data will not crash kernel.
-Proper fix: Set inline bytes to multiple of mbmaxlen and
-validate it (after the 8 byte length).');
+so bad data will not crash kernel.');
 select * from t1;
 drop table t1;
 
+# -- bug #19201
+create table t1 (
+  a int primary key not null auto_increment,
+  b text
+) engine=ndbcluster;
+--disable_query_log
+set autocommit=1;
+# more rows than batch size (64)
+# for this bug no blob parts would be necessary
+let $1 = 500;
+while ($1)
+{
+  insert into t1 (b) values (repeat('x',4000));
+  dec $1;
+}
+--enable_query_log
+select count(*) from t1;
+truncate t1;
+select count(*) from t1;
+drop table t1;
+
 # End of 4.1 tests
diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test
index 4787abe86e2..2fe54cac048 100644
--- a/mysql-test/t/ndb_config.test
+++ b/mysql-test/t/ndb_config.test
@@ -15,4 +15,3 @@
 --exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster0 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
 --exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster1 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
 --exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster2 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --query=type,nodeid,host --mycnf 2> /dev/null
---exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster2 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --ndb-shm --connections --query=type,nodeid1,nodeid2,group,nodeidserver --mycnf 2> /dev/null
diff --git a/mysql-test/t/ndb_config2.test b/mysql-test/t/ndb_config2.test
new file mode 100644
index 00000000000..170f1b2e5e7
--- /dev/null
+++ b/mysql-test/t/ndb_config2.test
@@ -0,0 +1,7 @@
+-- source include/have_ndb.inc
+-- source include/ndb_default_cluster.inc
+-- source include/not_embedded.inc
+
+# Following doesn't work in all configurations (if shm is not defined)
+
+--exec $NDB_TOOLS_DIR/ndb_config --defaults-group-suffix=.cluster2 --defaults-file=$MYSQL_TEST_DIR/std_data/ndb_config_mycnf2.cnf --ndb-shm --connections --query=type,nodeid1,nodeid2,group,nodeidserver --mycnf 2> /dev/null
diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test
index 4fb6422b359..700ff55c2d5 100644
--- a/mysql-test/t/ndb_index_unique.test
+++ b/mysql-test/t/ndb_index_unique.test
@@ -32,8 +32,8 @@ select * from t1 order by a;
 alter table t1 drop index ib;
 insert into t1 values(1, 2, 3);
 # Bug# #18129
-#--error 1169
-#create unique index ib on t1(b);
+--error 1169
+create unique index ib on t1(b);
 
 drop table t1;
 
diff --git a/mysql-test/t/ndb_partition_error.test b/mysql-test/t/ndb_partition_error.test
index 286c2216f70..06581f1270f 100644
--- a/mysql-test/t/ndb_partition_error.test
+++ b/mysql-test/t/ndb_partition_error.test
@@ -66,6 +66,6 @@ partition by list(a)
 partitions 2
 (partition x123 values in (11, 12),
  partition x234 values in (5, 1));
---error 1505
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 insert into t1 values (NULL,1,1);
 drop table t1;
diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test
index 183308880ed..4aec745f3f7 100644
--- a/mysql-test/t/null.test
+++ b/mysql-test/t/null.test
@@ -190,4 +190,45 @@ select
 # Restore charset to the default value.
 set names latin1;
 
+#
+# Bug#19145: mysqld crashes if you set the default value of an enum field to NULL
+#
+create table bug19145a (e enum('a','b','c')          default 'b' , s set('x', 'y', 'z')          default 'y' ) engine=MyISAM;
+create table bug19145b (e enum('a','b','c')          default null, s set('x', 'y', 'z')          default null) engine=MyISAM;
+
+create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM;
+
+# Invalid default value for 's'
+--error 1067
+create table bug19145setnotnulldefaultnull (e enum('a','b','c')          default null, s set('x', 'y', 'z') not null default null) engine=MyISAM;
+
+# Invalid default value for 'e'
+--error 1067
+create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z')          default null) engine=MyISAM;
+
+alter table bug19145a alter column e set default null;
+alter table bug19145a alter column s set default null;
+alter table bug19145a add column (i int);
+
+alter table bug19145b alter column e set default null;
+alter table bug19145b alter column s set default null;
+alter table bug19145b add column (i int);
+
+# Invalid default value for 'e'
+--error 1067
+alter table bug19145c alter column e set default null;
+
+# Invalid default value for 's'
+--error 1067
+alter table bug19145c alter column s set default null;
+alter table bug19145c add column (i int);
+
+show create table bug19145a;
+show create table bug19145b;
+show create table bug19145c;
+
+drop table bug19145a;
+drop table bug19145b;
+drop table bug19145c;
+
 # End of 4.1 tests
diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test
index 359b8b69a4d..4cc9113048f 100644
--- a/mysql-test/t/openssl_1.test
+++ b/mysql-test/t/openssl_1.test
@@ -48,9 +48,9 @@ select * from t1;
 delete from t1;
 
 connection default;
-delete from mysql.user where user='ssl_user%';
-delete from mysql.db where user='ssl_user%';
-flush privileges;
+drop user ssl_user1@localhost, ssl_user2@localhost,
+ssl_user3@localhost, ssl_user4@localhost;
+
 drop table t1;
 
 # End of 4.1 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 9ffdb72ca22..639a576fb35 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1110,4 +1110,40 @@ select * from t1 order by 1+1;
 
 drop table t1;
 
+#
+# Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS".
+# Add test coverage for the added commands.
+#
+create table t1 (a int);
+create table t2 like t1;
+create table t3 like t2;
+prepare stmt from "repair table t1";
+execute stmt;
+execute stmt;
+prepare stmt from "optimize table t1";
+execute stmt;
+execute stmt;
+prepare stmt from "analyze table t1";
+execute stmt;
+execute stmt;
+prepare stmt from "repair table t1, t2, t3";
+execute stmt;
+execute stmt;
+prepare stmt from "optimize table t1, t2, t3";
+execute stmt;
+execute stmt;
+prepare stmt from "analyze table t1, t2, t3";
+execute stmt;
+execute stmt;
+prepare stmt from "repair table t1, t4, t3";
+execute stmt;
+execute stmt;
+prepare stmt from "optimize table t1, t3, t4";
+execute stmt;
+execute stmt;
+prepare stmt from "analyze table t4, t1";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
 # End of 5.0 tests
diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test
index e214afeaaf3..ff1c87f3bd8 100644
--- a/mysql-test/t/ps_11bugs.test
+++ b/mysql-test/t/ps_11bugs.test
@@ -130,3 +130,17 @@ drop table t1, t2;
 # end of bug#1676
 
 # End of 4.1 tests
+
+# bug#18492: mysqld reports ER_ILLEGAL_REFERENCE in --ps-protocol
+
+create table t1 (a int primary key);
+insert into t1 values (1);
+
+explain select * from t1 where 3 in (select (1+1) union select 1);
+
+select * from t1 where 3 in (select (1+1) union select 1);
+
+prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)';
+execute st_18492;
+
+drop table t1;
diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test
index 6b168711de8..f61a7820afe 100644
--- a/mysql-test/t/ps_1general.test
+++ b/mysql-test/t/ps_1general.test
@@ -456,13 +456,10 @@ into table t1 fields terminated by ''\t'' ';
 prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
 execute stmt1 ;
 ## 
---error 1295
 prepare stmt1 from ' optimize table t1 ' ;
---error 1295
 prepare stmt1 from ' analyze table t1 ' ;
 --error 1295
 prepare stmt1 from ' checksum table t1 ' ;
---error 1295
 prepare stmt1 from ' repair table t1 ' ;
 --error 1295
 prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 7596a7ba708..e2ff20e6ecc 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -207,7 +207,7 @@ show status like "Qcache_queries_in_cache";
 drop table t1;
 
 #
-# Charset convertion (cp1251_koi8 always present)
+# Charset conversion (cp1251_koi8 always present)
 #
 create table t1 (a char(1) not null collate koi8r_general_ci);
 insert into t1 values(_koi8r"á");
diff --git a/mysql-test/t/rpl_loaddatalocal.test b/mysql-test/t/rpl_loaddatalocal.test
index af4fd0106bd..758ac94af24 100644
--- a/mysql-test/t/rpl_loaddatalocal.test
+++ b/mysql-test/t/rpl_loaddatalocal.test
@@ -53,11 +53,11 @@ create table t1(a int primary key);
 --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
 eval load data local infile '$MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1;
 system rm $MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile ;
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 save_master_pos;
 connection slave;
 sync_with_master;
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 connection master;
 drop table t1;
 save_master_pos;
diff --git a/mysql-test/t/rpl_openssl.test b/mysql-test/t/rpl_openssl.test
index 8a85443e71f..00ae5c935bf 100644
--- a/mysql-test/t/rpl_openssl.test
+++ b/mysql-test/t/rpl_openssl.test
@@ -53,6 +53,7 @@ stop slave;
 change master to master_user='root',master_password='', master_ssl=0;
 start slave;
 connection master;
+drop user replssl@localhost;
 drop table t1;
 save_master_pos;
 connection slave;
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index 7f76aaf3355..a5c8a87c74d 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -1,3 +1,6 @@
+# This test uses chmod, can't be run with root permissions
+-- source include/not_as_root.inc
+
 #
 # Test is run with max_binlog_size=2048 to force automatic rotation of the
 # binary log
diff --git a/mysql-test/t/rpl_sp_effects.test b/mysql-test/t/rpl_sp_effects.test
index c081f8e00c6..40c9a5d0b74 100644
--- a/mysql-test/t/rpl_sp_effects.test
+++ b/mysql-test/t/rpl_sp_effects.test
@@ -1,3 +1,9 @@
+##########################################
+# Change Author: JBM
+# Change Date: 2006-05-02
+# Change: Added Order By for NDB testing
+##########################################
+
 # Test of replication of stored procedures (WL#2146 for MySQL 5.0)
 -- source include/master-slave.inc
 
@@ -30,9 +36,9 @@ call p1();
 
 sync_slave_with_master;
 connection slave;
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 connection master;
-delete from t1;
+SELECT * FROM t1 ORDER BY a;
 
 # 2. Test SP variable name
 delimiter //;
@@ -44,10 +50,10 @@ end//
 delimiter ;//
 
 call p2();
-select * from t2;
+SELECT * FROM t2 ORDER BY a;
 sync_slave_with_master;
 connection slave;
-select * from t2;
+SELECT * FROM t2 ORDER BY a;
 
 connection master;
 drop procedure p1;
@@ -78,19 +84,19 @@ end//
 delimiter ;//
 
 call p1(f1(1), f1(2));
-select * from t1;
+SELECT * FROM t1 ORDER BY a;
 
 create table t2(a int);
 insert into t2 values (10),(11);
-select a,f1(a) from t2;
+SELECT a,f1(a) FROM t2 ORDER BY a;
 
 # This shouldn't put separate 'call f1(3)' into binlog:
 insert into t2 select f1(3);
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 
 sync_slave_with_master;
 connection slave;
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 
 connection master;
 drop procedure p1;
@@ -102,11 +108,11 @@ delete from t1;
 insert into t2 values(1),(2);
 create view v1 as select f1(a) from t2;
 select * from v1;
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 
 sync_slave_with_master;
 connection slave;
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 
 connection master;
 drop view v1;
@@ -116,11 +122,11 @@ delete from t1;
 prepare s1 from 'select f1(?)';
 set @xx=123;
 execute s1 using @xx;
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 
 sync_slave_with_master;
 connection slave;
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 
 connection master;
 delete from t1;
@@ -140,10 +146,10 @@ begin
 end//
 delimiter ;//
 call p1(15);
-select 'master:',a from t1;
+SELECT 'master:',a FROM t1 ORDER BY a;
 sync_slave_with_master;
 connection slave;
-select 'slave:',a from t1;
+SELECT 'slave:',a FROM t1 ORDER BY a;
 
 connection master;
 drop procedure p1;
@@ -188,10 +194,10 @@ select f1();
 set @x=30;
 call p1();
 
-select 'master', a from t1;
+SELECT 'master', a FROM t1 ORDER BY a;
 sync_slave_with_master;
 connection slave;
-select 'slave', a from t1;
+SELECT 'slave', a FROM t1 ORDER BY a;
 
 connection master;
 drop table t1;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index c4fe1906cbc..8e3c5847846 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2871,3 +2871,18 @@ SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
 
 
 DROP TABLE t1,t2;
+
+#
+# Bug#18712: Truncation problem (needs just documenting and test
+# cases to prevent fixing this accidently. It is intended behaviour)
+#
+
+CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
+INSERT t1 SET i = 0;
+UPDATE t1 SET i = -1;
+SELECT * FROM t1;
+UPDATE t1 SET i = CAST(i - 1 AS SIGNED);
+SELECT * FROM t1;
+UPDATE t1 SET i = i - 1;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test
index f369dc64b0e..a8c3c0a22eb 100644
--- a/mysql-test/t/sp-security.test
+++ b/mysql-test/t/sp-security.test
@@ -545,6 +545,7 @@ GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost;
 # Cleanup.
 
 DROP DATABASE db_bug7787;
+drop user user_bug7787@localhost;
 use test;
 
 
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
index 3854297ec0c..0adbeb2d98b 100644
--- a/mysql-test/t/sp_notembedded.test
+++ b/mysql-test/t/sp_notembedded.test
@@ -1,6 +1,10 @@
 # Can't test with embedded server
 -- source include/not_embedded.inc
 
+--sleep 2
+--disable_warnings
+drop table if exists t1,t3;
+--enable_warnings
 delimiter |;
 
 #
@@ -258,5 +262,6 @@ drop procedure bug10100pv|
 drop procedure bug10100pd|
 drop procedure bug10100pc|
 drop view v1|
+drop table t3|
 
 delimiter ;|
diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test
index 069c19341e4..bfc909d6995 100644
--- a/mysql-test/t/timezone2.test
+++ b/mysql-test/t/timezone2.test
@@ -3,6 +3,7 @@
 # Preparing playground
 --disable_warnings
 drop table if exists t1, t2;
+drop function if exists f1;
 --enable_warnings
 
 
@@ -222,3 +223,22 @@ select * from t1;
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Test for bug #11081 "Using a CONVERT_TZ function in a stored function
+# or trigger fails".
+#
+create table t1 (ldt datetime, udt datetime);
+create function f1(i datetime) returns datetime
+  return convert_tz(i, 'UTC', 'Europe/Moscow');
+create trigger t1_bi before insert on t1 for each row
+  set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
+# This should work without errors
+insert into t1 (ldt) values ('2006-04-19 16:30:00');
+select * from t1;
+# This should work without errors as well
+select ldt, f1(udt) as ldt2 from t1;
+drop table t1;
+drop function f1;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index ae05d70bf67..00c85a650d1 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1111,7 +1111,7 @@ insert into t1 values
 create function f2() returns int return (select max(b) from t2);
 insert into t2 select a, f2() from t1;
 load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
-drop tables t1, t2;
+drop table t1, t2;
 drop function f1;
 drop function f2;
 
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index c9f22cf410b..e2556692612 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -14,18 +14,26 @@ drop table if exists t1;
 # Create the example functions from udf_example
 #
 
-CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
-CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
 
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
 --error ER_CANT_FIND_DL_ENTRY
-CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME 'udf_example.so';
-CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
-CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so";
-CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
-CREATE FUNCTION reverse_lookup
-        RETURNS STRING SONAME 'udf_example.so';
-CREATE AGGREGATE FUNCTION avgcost
-        RETURNS REAL SONAME 'udf_example.so';
+eval CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION sequence RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION lookup RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION reverse_lookup
+        RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE AGGREGATE FUNCTION avgcost
+        RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
 
 --error 0
 select myfunc_double();
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 61861c26ea8..e1b23a1782f 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -143,8 +143,6 @@ select @@Max_Allowed_Packet;
 select @@version;
 --replace_column 1 #
 select @@global.version;
---replace_column 1 #
-select @@session.VERSION;
 
 # End of 4.1 tests
 
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 649265dcc5e..018337f2631 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -169,7 +169,7 @@ set collation_connection=NULL;
 set global autocommit=1;
 --error 1238
 select @@global.timestamp;
---error 1193
+--error 1238 
 set @@version='';
 --error 1229
 set @@concurrent_insert=1;
@@ -258,6 +258,8 @@ select @@sql_max_join_size,@@max_join_size;
 set sql_quote_show_create=1;
 set sql_safe_updates=1;
 set sql_select_limit=1;
+# reset it, so later tests don't get confused
+set sql_select_limit=default;
 set sql_warnings=1;
 set global table_open_cache=100;
 set storage_engine=myisam;
@@ -472,4 +474,38 @@ select @@character_set_filesystem;
 set @@global.character_set_filesystem=default;
 select @@global.character_set_filesystem;
 
-# End of 5.0 tests
+#
+# Bug #17849: Show sql_big_selects in SHOW VARIABLES
+#
+set @old_sql_big_selects = @@sql_big_selects;
+set @@sql_big_selects = 1;
+show variables like 'sql_big_selects';
+set @@sql_big_selects = @old_sql_big_selects;
+
+#
+# Bug #16195: SHOW VARIABLES doesn't report correctly sql_warnings and
+# sql_notes values
+# 
+set @@sql_notes = 0, @@sql_warnings = 0;
+show variables like 'sql_notes';
+show variables like 'sql_warnings';
+set @@sql_notes = 1, @@sql_warnings = 1;
+show variables like 'sql_notes';
+show variables like 'sql_warnings';
+
+#
+# Bug #12792: @@system_time_zone is not SELECTable.
+#
+# Don't actually output, since it depends on the system
+--replace_column 1 #
+select @@system_time_zone;
+
+#
+# Bug #15684: system variables cannot be SELECTed (e.g. @@version_comment)
+#
+# Don't actually output, since it depends on the system
+--replace_column 1 # 2 # 3 # 4 #
+select @@version, @@version_comment, @@version_compile_machine,
+       @@version_compile_os;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 8335c1de20a..8deff474587 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -32,7 +32,7 @@ grant create view,select on test.* to mysqltest_1@localhost;
 connect (user1,localhost,mysqltest_1,,test);
 connection user1;
 
--- error ER_SPECIFIC_ACCESS_DENIED
+-- error ER_SPECIFIC_ACCESS_DENIED_ERROR
 create definer=root@localhost view v1 as select * from mysqltest.t1;
 create view v1 as select * from mysqltest.t1;
 # try to modify view without DROP privilege on it
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index 8a12dbca51d..65d0a40291f 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -335,3 +335,11 @@ END//
 DELIMITER ;//
 CALL p2();
 DROP PROCEDURE p2;
+
+#
+# Bug#18170: XML: ExtractValue():
+# XPath expression can't use QNames (colon in names)
+#
+select extractValue('','count(ns:element)');
+select extractValue('a','/ns:element');
+select extractValue('a','/ns:element/@xmlns:ns');
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 7a66164b775..abc5cc142f5 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -53,6 +53,7 @@ libmysys_a_SOURCES =    my_init.c my_getwd.c mf_getdate.c my_mmap.c \
 			charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
 			my_gethostbyname.c rijndael.c my_aes.c sha1.c \
 			my_handler.c my_netware.c my_largepage.c \
+			my_memmem.c \
 			my_windac.c my_access.c base64.c
 EXTRA_DIST =		thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
 			thr_mutex.c thr_rwlock.c \
diff --git a/mysys/cmakelists.txt b/mysys/cmakelists.txt
index 5a3b8f1657e..4aa99a70121 100644
--- a/mysys/cmakelists.txt
+++ b/mysys/cmakelists.txt
@@ -26,4 +26,4 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m
 				my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
 				my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
 				rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
-				thr_rwlock.c tree.c typelib.c my_vle.c base64.c)
+				thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c)
diff --git a/mysys/errors.c b/mysys/errors.c
index 4472b7173fa..5fe9eadb522 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -39,7 +39,7 @@ const char * NEAR globerrs[GLOBERRS]=
   "Can't get working dirctory (Errcode: %d)",
   "Can't change dir to '%s' (Errcode: %d)",
   "Warning: '%s' had %d links",
-  "%d files and %d streams is left open\n",
+  "Warning: %d files and %d streams is left open\n",
   "Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... Retry in %d secs",
   "Can't create directory '%s' (Errcode: %d)",
   "Character set '%s' is not a compiled character set and is not specified in the '%s' file",
@@ -50,6 +50,7 @@ const char * NEAR globerrs[GLOBERRS]=
   "Can't sync file '%s' to disk (Errcode: %d)",
   "Collation '%s' is not a compiled collation and is not specified in the '%s' file",
   "File '%s' not found (Errcode: %d)",
+  "File '%s' (fileno: %d) was not closed"
 };
 
 void init_glob_errs(void)
@@ -78,7 +79,7 @@ void init_glob_errs()
   EE(EE_GETWD)		= "Can't get working dirctory (Errcode: %d)";
   EE(EE_SETWD)		= "Can't change dir to '%s' (Errcode: %d)";
   EE(EE_LINK_WARNING)	= "Warning: '%s' had %d links";
-  EE(EE_OPEN_WARNING)	= "%d files and %d streams is left open\n";
+  EE(EE_OPEN_WARNING)	= "Warning: %d files and %d streams is left open\n";
   EE(EE_DISK_FULL)	= "Disk is full writing '%s'. Waiting for someone to free space...";
   EE(EE_CANT_MKDIR)	="Can't create directory '%s' (Errcode: %d)";
   EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
@@ -89,5 +90,6 @@ void init_glob_errs()
   EE(EE_SYNC)=		"Can't sync file '%s' to disk (Errcode: %d)";
   EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file";
   EE(EE_FILENOTFOUND)	= "File '%s' not found (Errcode: %d)";
+  EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
 }
 #endif
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index e181ccfb88d..f1ea21c2a47 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -252,37 +252,89 @@ uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
 uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
 {
   uint out_length=0;
+  uint minimum_width; /* as yet unimplemented */
+  uint minimum_width_sign;
+  uint precision; /* as yet unimplemented for anything but %b */
 
-  for (; *fmt ; fmt++)
+  /*
+    Store the location of the beginning of a format directive, for the
+    case where we learn we shouldn't have been parsing a format string
+    at all, and we don't want to lose the flag/precision/width/size
+    information.
+   */
+  const char* backtrack;
+
+  for (; *fmt != '\0'; fmt++)
   {
-    if (*fmt++ != '%')
+    /* Copy everything until '%' or end of string */
+    const char *start=fmt;
+    uint length;
+    
+    for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ;
+
+    length= (uint) (fmt - start);
+    out_length+=length;
+    if (my_b_write(info, start, length))
+      goto err;
+
+    if (*fmt == '\0')				/* End of format */
     {
-      /* Copy everything until '%' or end of string */
-      const char *start=fmt-1;
-      uint length;
-      for (; *fmt && *fmt != '%' ; fmt++ ) ;
-      length= (uint) (fmt - start);
-      out_length+=length;
-      if (my_b_write(info, start, length))
-	goto err;
-      if (!*fmt)				/* End of format */
-      {
-	return out_length;
-      }
-      fmt++;
-      /* Found one '%' */
+      return out_length;
     }
+
+    /* 
+      By this point, *fmt must be a percent;  Keep track of this location and
+      skip over the percent character. 
+    */
+    DBUG_ASSERT(*fmt == '%');
+    backtrack= fmt;
+    fmt++;
+
+    minimum_width= 0;
+    precision= 0;
+    minimum_width_sign= 1;
     /* Skip if max size is used (to be compatible with printf) */
-    while (my_isdigit(&my_charset_latin1, *fmt) || *fmt == '.' || *fmt == '-')
+    while (*fmt == '-') { fmt++; minimum_width_sign= -1; }
+    if (*fmt == '*') {
+      precision= (int) va_arg(args, int);
       fmt++;
+    } else {
+      while (my_isdigit(&my_charset_latin1, *fmt)) {
+        minimum_width=(minimum_width * 10) + (*fmt - '0');
+        fmt++;
+      }
+    }
+    minimum_width*= minimum_width_sign;
+
+    if (*fmt == '.') {
+      fmt++;
+      if (*fmt == '*') {
+        precision= (int) va_arg(args, int);
+        fmt++;
+      } else {
+        while (my_isdigit(&my_charset_latin1, *fmt)) {
+          precision=(precision * 10) + (*fmt - '0');
+          fmt++;
+        }
+      }
+    }
+
     if (*fmt == 's')				/* String parameter */
     {
       reg2 char *par = va_arg(args, char *);
       uint length = (uint) strlen(par);
+      /* TODO: implement minimum width and precision */
       out_length+=length;
       if (my_b_write(info, par, length))
 	goto err;
     }
+    else if (*fmt == 'b')                       /* Sized buffer parameter, only precision makes sense */
+    {
+      char *par = va_arg(args, char *);
+      out_length+= precision;
+      if (my_b_write(info, par, precision))
+        goto err;
+    }
     else if (*fmt == 'd' || *fmt == 'u')	/* Integer parameter */
     {
       register int iarg;
@@ -317,9 +369,9 @@ uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
     else
     {
       /* %% or unknown code */
-      if (my_b_write(info, "%", 1))
-	goto err;
-      out_length++;
+      if (my_b_write(info, backtrack, fmt-backtrack))
+        goto err;
+      out_length+= fmt-backtrack;
     }
   }
   return out_length;
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index bf8986fe05b..1dab9a47ed8 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -262,15 +262,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond);
 #define keycache_pthread_cond_signal pthread_cond_signal
 #endif /* defined(KEYCACHE_DEBUG) */
 
-static uint next_power(uint value)
+static inline uint next_power(uint value)
 {
-  uint old_value= 1;
-  while (value)
-  {
-    old_value= value;
-    value&= value-1;
-  }
-  return (old_value << 1);
+  return (uint) my_round_up_to_next_power((uint32) value) << 1;
 }
 
 
diff --git a/mysys/my_bit.c b/mysys/my_bit.c
index 01c9b5ea68d..6ef0e171695 100644
--- a/mysys/my_bit.c
+++ b/mysys/my_bit.c
@@ -76,3 +76,33 @@ uint my_count_bits_ushort(ushort v)
   return nbits[v];
 }
 
+
+/*
+  Next highest power of two
+
+  SYNOPSIS
+    my_round_up_to_next_power()
+    v		Value to check
+
+  RETURN
+    Next or equal power of 2
+    Note: 0 will return 0
+
+  NOTES
+    Algorithm by Sean Anderson, according to:
+    http://graphics.stanford.edu/~seander/bithacks.html
+    (Orignal code public domain)
+
+    Comments shows how this works with 01100000000000000000000000001011
+*/
+
+uint32 my_round_up_to_next_power(uint32 v)
+{
+  v--;			/* 01100000000000000000000000001010 */
+  v|= v >> 1;		/* 01110000000000000000000000001111 */
+  v|= v >> 2;		/* 01111100000000000000000000001111 */
+  v|= v >> 4;		/* 01111111110000000000000000001111 */
+  v|= v >> 8;		/* 01111111111111111100000000001111 */
+  v|= v >> 16;		/* 01111111111111111111111111111111 */
+  return v+1;		/* 10000000000000000000000000000000 */
+}
diff --git a/mysys/my_file.c b/mysys/my_file.c
index 4c333c7d7db..0abc031a195 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -107,7 +107,10 @@ uint my_set_max_open_files(uint files)
     DBUG_RETURN(MY_NFILE);
 
   /* Copy any initialized files */
-  memcpy((char*) tmp, (char*) my_file_info, sizeof(*tmp) * my_file_limit);
+  memcpy((char*) tmp, (char*) my_file_info,
+         sizeof(*tmp) * min(my_file_limit, files));
+  bzero((char*) (tmp + my_file_limit),
+        max((int) (files- my_file_limit), 0)*sizeof(*tmp));
   my_free_open_file_info();			/* Free if already allocated */
   my_file_info= tmp;
   my_file_limit= files;
@@ -121,8 +124,12 @@ void my_free_open_file_info()
   DBUG_ENTER("my_free_file_info");
   if (my_file_info != my_file_info_default)
   {
+    /* Copy data back for my_print_open_files */
+    memcpy((char*) my_file_info_default, my_file_info,
+           sizeof(*my_file_info_default)* MY_NFILE);
     my_free((char*) my_file_info, MYF(0));
     my_file_info= my_file_info_default;
+    my_file_limit= MY_NFILE;
   }
   DBUG_VOID_RETURN;
 }
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 88b8e457bd6..4d7299c7cb1 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -150,6 +150,7 @@ void my_end(int infoflag)
       sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened);
       (void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL);
       DBUG_PRINT("error",("%s",errbuff[0]));
+      my_print_open_files();
     }
   }
   free_charsets();
diff --git a/mysys/my_memmem.c b/mysys/my_memmem.c
new file mode 100644
index 00000000000..682a1314f09
--- /dev/null
+++ b/mysys/my_memmem.c
@@ -0,0 +1,66 @@
+#include "my_base.h"
+
+/*
+  my_memmem, port of a GNU extension.
+
+  Returns a pointer to the beginning of the substring, needle, or NULL if the
+  substring is not found in haystack.
+*/
+void *my_memmem(const void *haystack, size_t haystacklen,
+    const void *needle, size_t needlelen)
+{
+  const unsigned char *cursor;
+  const unsigned char *last_possible_needle_location =
+    (unsigned char *)haystack + haystacklen - needlelen;
+
+  /* Easy answers */
+  if (needlelen > haystacklen) return(NULL);
+  if (needle == NULL) return(NULL);
+  if (haystack == NULL) return(NULL);
+  if (needlelen == 0) return(NULL);
+  if (haystacklen == 0) return(NULL);
+
+  for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) {
+    if (memcmp(needle, cursor, needlelen) == 0) {
+      return((void *) cursor);
+    }
+  }
+  return(NULL);
+}
+
+  
+
+#ifdef MAIN
+#include 
+
+int main(int argc, char *argv[]) {
+  char haystack[10], needle[3];
+
+  memmove(haystack, "0123456789", 10);
+
+  memmove(needle, "no", 2);
+  assert(my_memmem(haystack, 10, needle, 2) == NULL);
+
+  memmove(needle, "345", 3);
+  assert(my_memmem(haystack, 10, needle, 3) != NULL);
+
+  memmove(needle, "789", 3);
+  assert(my_memmem(haystack, 10, needle, 3) != NULL);
+  assert(my_memmem(haystack, 9, needle, 3) == NULL);
+
+  memmove(needle, "012", 3);
+  assert(my_memmem(haystack, 10, needle, 3) != NULL);
+  assert(my_memmem(NULL, 10, needle, 3) == NULL);
+
+  assert(my_memmem(NULL, 10, needle, 3) == NULL);
+  assert(my_memmem(haystack, 0, needle, 3) == NULL);
+  assert(my_memmem(haystack, 10, NULL, 3) == NULL);
+  assert(my_memmem(haystack, 10, needle, 0) == NULL);
+
+  assert(my_memmem(haystack, 1, needle, 3) == NULL);
+
+  printf("success\n");
+  return(0);
+}
+
+#endif
diff --git a/mysys/my_open.c b/mysys/my_open.c
index 098d410d8ce..ed323b3b1ad 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -351,3 +351,24 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode)
   return fh;                        /* return handle */
 }
 #endif /* __WIN__ */
+
+
+#ifdef EXTRA_DEBUG
+
+void my_print_open_files(void)
+{
+  if (my_file_opened | my_stream_opened)
+  {
+    uint i;
+    for (i= 0 ; i < my_file_limit ; i++)
+    {
+      if (my_file_info[i].type != UNOPEN)
+      {
+        fprintf(stderr, EE(EE_FILE_NOT_CLOSED), my_file_info[i].name, i);
+        fputc('\n', stderr);
+      }
+    }
+  }
+}
+
+#endif
diff --git a/mysys/tree.c b/mysys/tree.c
index 1780913961e..0c9c04919b0 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -271,7 +271,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
   return element;
 }
 
-int tree_delete(TREE *tree, void *key, void *custom_arg)
+int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg)
 {
   int cmp,remove_colour;
   TREE_ELEMENT *element,***parent, ***org_parent, *nod;
@@ -326,8 +326,7 @@ int tree_delete(TREE *tree, void *key, void *custom_arg)
     rb_delete_fixup(tree,parent);
   if (tree->free)
     (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
-  /* This doesn't include key_size, but better than nothing */
-  tree->allocated-= sizeof(TREE_ELEMENT)+tree->size_of_element;
+  tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size;
   my_free((gptr) element,MYF(0));
   tree->elements_in_tree--;
   return 0;
diff --git a/plugin/Makefile.am b/plugin/Makefile.am
index d0f68a9c84b..6dee710103e 100644
--- a/plugin/Makefile.am
+++ b/plugin/Makefile.am
@@ -1,6 +1,28 @@
-SUBDIRS= fulltext
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# Process this file with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS =	foreign
 
 # extra plugin example files are listed here, to
 # keep its Makefile.am cleaner as a template
-EXTRA_DIST= fulltext/configure.in
+EXTRA_DIST =	fulltext/configure.in	
 
+SUBDIRS =	@mysql_pg_dirs@
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c
index cdf1527b310..9b937453ce4 100644
--- a/plugin/fulltext/plugin_example.c
+++ b/plugin/fulltext/plugin_example.c
@@ -216,7 +216,7 @@ static struct st_mysql_show_var simple_status[]=
   Plugin library descriptor
 */
 
-mysql_declare_plugin
+mysql_declare_plugin(ftexample)
 {
   MYSQL_FTPARSER_PLUGIN,      /* type                            */
   &simple_parser_descriptor,  /* descriptor                      */
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 06a6e1ebc63..8bbd362a15b 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -22,6 +22,7 @@
 
 #include "parse_output.h"
 #include "buffer.h"
+#include "log.h"
 
 #include 
 #include 
@@ -148,6 +149,60 @@ int Instance_options::fill_instance_version()
     mysqld_version= strdup_root(&alloc, start);
   }
 err:
+  if (rc)
+    log_error("fill_instance_version: Failed to get version of '%s'",
+              mysqld_path);
+  return rc;
+}
+
+
+/*
+  Fill mysqld_real_path
+
+  SYNOPSYS
+    fill_mysqld_real_path()
+
+  DESCRIPTION
+
+  Get the real path to mysqld from "mysqld --help" output.
+  Will print the realpath of mysqld between "Usage: " and "[OPTIONS]"
+
+  This is needed if the mysqld_path variable is pointing at a
+  script(for example libtool) or a symlink.
+
+  RETURN
+    0 - ok
+    1 - error occured
+*/
+
+int Instance_options::fill_mysqld_real_path()
+{
+  char result[FN_REFLEN];
+  char help_option[]= " --no-defaults --help";
+  int rc= 1;
+  Buffer cmd(mysqld_path_len + sizeof(help_option));
+
+  if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len,
+                            help_option, sizeof(help_option)))
+    goto err;
+
+  bzero(result, FN_REFLEN);
+
+  rc= parse_output_and_get_value(cmd.buffer, "Usage: ",
+                                 result, FN_REFLEN,
+                                 GET_LINE);
+
+  if (*result != '\0')
+  {
+    char* options_str;
+    /* chop the path of at [OPTIONS] */
+    if ((options_str= strstr(result, "[OPTIONS]")))
+      *options_str= '\0';
+    mysqld_real_path= strdup_root(&alloc, result);
+  }
+err:
+  if (rc)
+    log_error("fill_mysqld_real_path: Failed to get real path of mysqld");
   return rc;
 }
 
@@ -408,7 +463,7 @@ int Instance_options::complete_initialization(const char *default_path,
          options_array.elements*sizeof(char*));
   argv[filled_default_options + options_array.elements]= 0;
 
-  if (fill_log_options() || fill_instance_version())
+  if (fill_log_options() || fill_mysqld_real_path() || fill_instance_version())
     goto err;
 
   return 0;
diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h
index dae1c2695d1..b316dbf00fc 100644
--- a/server-tools/instance-manager/instance_options.h
+++ b/server-tools/instance-manager/instance_options.h
@@ -44,7 +44,8 @@ public:
   Instance_options() :
     mysqld_version(0), mysqld_socket(0), mysqld_datadir(0),
     mysqld_bind_address(0), mysqld_pid_file(0), mysqld_port(0),
-    mysqld_port_val(0), mysqld_path(0), nonguarded(0), shutdown_delay(0),
+    mysqld_port_val(0), mysqld_path(0), mysqld_real_path(0),
+    nonguarded(0), shutdown_delay(0),
     shutdown_delay_val(0), filled_default_options(0)
   {}
   ~Instance_options();
@@ -84,6 +85,7 @@ public:
   uint instance_name_len;
   const char *mysqld_path;
   uint mysqld_path_len;
+  const char *mysqld_real_path;
   const char *nonguarded;
   const char *shutdown_delay;
   uint shutdown_delay_val;
@@ -95,6 +97,7 @@ public:
 private:
   int fill_log_options();
   int fill_instance_version();
+  int fill_mysqld_real_path();
   int add_to_argv(const char *option);
   int get_default_option(char *result, size_t result_len,
                          const char *option_name);
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 60e7891931f..ba9b58c0c5e 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -30,10 +30,7 @@ libexec_PROGRAMS =	mysqld
 noinst_PROGRAMS =	gen_lex_hash
 bin_PROGRAMS =		mysql_tzinfo_to_sql
 gen_lex_hash_LDFLAGS =  @NOINST_LDFLAGS@
-LDADD =			$(top_builddir)/storage/myisam/libmyisam.a \
-			$(top_builddir)/storage/myisammrg/libmyisammrg.a \
-			$(top_builddir)/storage/heap/libheap.a \
-			$(top_builddir)/vio/libvio.a \
+LDADD =			$(top_builddir)/vio/libvio.a \
 			$(top_builddir)/mysys/libmysys.a \
 			$(top_builddir)/dbug/libdbug.a \
 			$(top_builddir)/regex/libregex.a \
@@ -41,7 +38,7 @@ LDADD =			$(top_builddir)/storage/myisam/libmyisam.a \
 
 mysqld_LDADD =		@MYSQLD_EXTRA_LDFLAGS@ \
 			@pstack_libs@ \
-			@mysql_se_objs@ @mysql_se_libs@ \
+			@mysql_plugin_libs@ \
 			$(LDADD)  $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
                         @yassl_libs@ @openssl_libs@
 noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
@@ -53,20 +50,23 @@ noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
 			sql_manager.h sql_map.h sql_string.h unireg.h \
 			sql_error.h field.h handler.h mysqld_suffix.h \
 			ha_heap.h ha_myisam.h ha_myisammrg.h ha_partition.h \
+			ha_innodb.h  ha_berkeley.h ha_federated.h \
+			ha_ndbcluster.h ha_ndbcluster_binlog.h \
+			ha_ndbcluster_tables.h \
 			opt_range.h protocol.h rpl_tblmap.h \
 			log.h sql_show.h rpl_rli.h \
-			sql_select.h structs.h table.h sql_udf.h hash_filo.h\
+			sql_select.h structs.h table.h sql_udf.h hash_filo.h \
 			lex.h lex_symbol.h sql_acl.h sql_crypt.h  \
 			log_event.h sql_repl.h slave.h rpl_filter.h \
 			rpl_injector.h \
 			stacktrace.h sql_sort.h sql_cache.h set_var.h \
 			spatial.h gstream.h client_settings.h tzfile.h \
-                        tztime.h my_decimal.h\
+			tztime.h my_decimal.h\
 			sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
 			parse_file.h sql_view.h	sql_trigger.h \
 			sql_array.h sql_cursor.h event.h event_priv.h \
 			sql_plugin.h authors.h sql_partition.h \
-                        partition_info.h partition_element.h
+			partition_info.h partition_element.h
 mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			item.cc item_sum.cc item_buff.cc item_func.cc \
 			item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
@@ -79,7 +79,7 @@ mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			mysqld.cc password.c hash_filo.cc hostname.cc \
 			set_var.cc sql_parse.cc sql_yacc.yy \
 			sql_base.cc table.cc sql_select.cc sql_insert.cc \
-                        sql_prepare.cc sql_error.cc \
+			sql_prepare.cc sql_error.cc \
 			sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
 			procedure.cc item_uniq.cc sql_test.cc \
 			log.cc log_event.cc init.cc derror.cc sql_acl.cc \
@@ -87,6 +87,9 @@ mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			discover.cc time.cc opt_range.cc opt_sum.cc \
 		   	records.cc filesort.cc handler.cc \
 			ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
+			ha_partition.cc ha_innodb.cc ha_berkeley.cc \
+			ha_federated.cc \
+                        ha_ndbcluster.cc ha_ndbcluster_binlog.cc \
 			sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
 			sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
 			sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
@@ -102,15 +105,9 @@ mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			sp_cache.cc parse_file.cc sql_trigger.cc \
                         event_executor.cc event.cc event_timed.cc \
 			sql_plugin.cc sql_binlog.cc \
-			handlerton.cc sql_tablespace.cc partition_info.cc
-EXTRA_mysqld_SOURCES =	ha_innodb.cc ha_berkeley.cc ha_archive.cc \
-			ha_innodb.h  ha_berkeley.h  ha_archive.h \
-			ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
-			ha_blackhole.h  ha_federated.h  ha_ndbcluster.h \
-			ha_ndbcluster_binlog.cc ha_ndbcluster_binlog.h \
-			ha_ndbcluster_tables.h \
-			ha_partition.cc ha_partition.h
-mysqld_DEPENDENCIES =	@mysql_se_objs@
+			sql_builtin.cc sql_tablespace.cc partition_info.cc
+
+
 gen_lex_hash_SOURCES =	gen_lex_hash.cc
 gen_lex_hash_LDADD =	$(LDADD) $(CXXLDFLAGS)
 mysql_tzinfo_to_sql_SOURCES =   mysql_tzinfo_to_sql.cc
@@ -162,6 +159,7 @@ sql_yacc.o:	sql_yacc.cc sql_yacc.h $(HEADERS)
 lex_hash.h:	gen_lex_hash$(EXEEXT)
 		./gen_lex_hash$(EXEEXT) > $@
 
+# the following three should eventually be moved out of this directory
 ha_berkeley.o:	ha_berkeley.cc ha_berkeley.h
 		$(CXXCOMPILE) @bdb_includes@ $(LM_CFLAGS) -c $<
 
diff --git a/sql/cmakelists.txt b/sql/cmakelists.txt
index 381d22c605c..05b1efdbe51 100644
--- a/sql/cmakelists.txt
+++ b/sql/cmakelists.txt
@@ -16,7 +16,7 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/message.rc
 							${CMAKE_SOURCE_DIR}/sql/sql_yacc.h 
 							${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc
                             ${CMAKE_SOURCE_DIR}/include/mysql_version.h
-                            ${CMAKE_SOURCE_DIR}/sql/handlerton.cc
+                            ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc
                             ${CMAKE_SOURCE_DIR}/sql/lex_hash.h 
                             ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
                             ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h
@@ -29,7 +29,8 @@ ADD_DEFINITIONS(-DHAVE_ROW_BASED_REPLICATION -DMYSQL_SERVER
 ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc
                discover.cc ../libmysql/errmsg.c field.cc field_conv.cc 
                filesort.cc gstream.cc  ha_heap.cc ha_myisam.cc ha_myisammrg.cc
-               ${mysql_se_ha_src} handler.cc hash_filo.cc hash_filo.h 
+               ha_innodb.cc ha_partition.cc ha_federated.cc ha_berkeley.cc
+               handler.cc hash_filo.cc hash_filo.h 
                hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc 
                item_create.cc item_func.cc item_geofunc.cc item_row.cc 
                item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc 
@@ -59,13 +60,19 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc
 			   ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h 
 			   ${PROJECT_SOURCE_DIR}/include/sql_state.h
 			   ${PROJECT_SOURCE_DIR}/include/mysql_version.h 
-			   ${PROJECT_SOURCE_DIR}/sql/handlerton.cc
+			   ${PROJECT_SOURCE_DIR}/sql/sql_builtin.cc
 			   ${PROJECT_SOURCE_DIR}/sql/lex_hash.h)
 TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg mysys yassl zlib dbug yassl 
                       taocrypt strings vio regex wsock32)
 IF(WITH_ARCHIVE_STORAGE_ENGINE)
   TARGET_LINK_LIBRARIES(mysqld archive)
 ENDIF(WITH_ARCHIVE_STORAGE_ENGINE)
+IF(WITH_BLACKHOLE_STORAGE_ENGINE)
+  TARGET_LINK_LIBRARIES(mysqld blackhole)
+ENDIF(WITH_BLACKHOLE_STORAGE_ENGINE)
+IF(WITH_CSV_STORAGE_ENGINE)
+  TARGET_LINK_LIBRARIES(mysqld csv)
+ENDIF(WITH_CSV_STORAGE_ENGINE)
 IF(WITH_EXAMPLE_STORAGE_ENGINE)
   TARGET_LINK_LIBRARIES(mysqld example)
 ENDIF(WITH_EXAMPLE_STORAGE_ENGINE)
diff --git a/sql/event_timed.cc b/sql/event_timed.cc
index adf28b8877c..879f4d6a3c9 100644
--- a/sql/event_timed.cc
+++ b/sql/event_timed.cc
@@ -19,10 +19,6 @@
 #include "event.h"
 #include "sp.h"
 
-
-
-extern int MYSQLparse(void *thd);
-
 /*
   Init all member variables
 
@@ -106,6 +102,9 @@ Event_timed::init_name(THD *thd, sp_name *spn)
   NOTE
     The body is extracted by copying all data between the
     start of the body set by another method and the current pointer in Lex.
+ 
+    Some questionable removal of characters is done in here, and that part
+    should be refactored when the parser is smarter.
 */
 
 void
@@ -116,9 +115,46 @@ Event_timed::init_body(THD *thd)
              body_begin, thd->lex->ptr));
 
   body.length= thd->lex->ptr - body_begin;
-  /* Trim nuls at the end */
-  while (body.length && body_begin[body.length-1] == '\0')
-    body.length--;
+  const uchar *body_end= body_begin + body.length - 1;
+
+  /* Trim nuls or close-comments ('*'+'/') or spaces at the end */
+  while (body_begin < body_end)
+  {
+
+    if ((*body_end == '\0') || 
+        (my_isspace(thd->variables.character_set_client, *body_end)))
+    { /* consume NULs and meaningless whitespace */
+      --body.length;
+      --body_end;
+      continue;
+    }
+
+    /*  
+       consume closing comments
+
+       This is arguably wrong, but it's the best we have until the parser is
+       changed to be smarter.   FIXME PARSER 
+
+       See also the sp_head code, where something like this is done also.
+
+       One idea is to keep in the lexer structure the count of the number of
+       open-comments we've entered, and scan left-to-right looking for a
+       closing comment IFF the count is greater than zero.
+
+       Another idea is to remove the closing comment-characters wholly in the
+       parser, since that's where it "removes" the opening characters.
+    */
+    if ((*(body_end - 1) == '*') && (*body_end == '/'))
+    {
+      DBUG_PRINT("info", ("consumend one '*" "/' comment in the query '%s'", 
+          body_begin));
+      body.length-= 2;
+      body_end-= 2;
+      continue;
+    }
+
+    break;  /* none were found, so we have excised all we can. */
+  }
 
   /* the first is always whitespace which I cannot skip in the parser */
   while (my_isspace(thd->variables.character_set_client, *body_begin))
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 6ea4cc9aeb5..473fb149871 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -56,10 +56,14 @@
 #include 
 #include 
 #include 
+
+#ifdef WITH_BERKELEY_STORAGE_ENGINE
 #include "ha_berkeley.h"
 #include "sql_manager.h"
 #include 
 
+#include 
+
 #define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
 #define HA_BERKELEY_RANGE_COUNT   100
 #define HA_BERKELEY_MAX_ROWS	  10000000 /* Max rows in table */
@@ -121,11 +125,15 @@ static int berkeley_savepoint(THD* thd, void *savepoint);
 static int berkeley_release_savepoint(THD* thd, void *savepoint);
 static handler *berkeley_create_handler(TABLE_SHARE *table);
 
+static const char berkeley_hton_name[]= "BerkeleyDB";
+static const char berkeley_hton_comment[]=
+  "Supports transactions and page-level locking";
+
 handlerton berkeley_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "BerkeleyDB",
+  berkeley_hton_name,
   SHOW_OPTION_YES,
-  "Supports transactions and page-level locking", 
+  berkeley_hton_comment, 
   DB_TYPE_BERKELEY_DB,
   berkeley_init,
   0, /* slot */
@@ -2725,3 +2733,18 @@ bool ha_berkeley::check_if_incompatible_data(HA_CREATE_INFO *info,
 }
 
 
+mysql_declare_plugin(berkeley)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &berkeley_hton,
+  berkeley_hton_name,
+  "Sleepycat Software",
+  berkeley_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100, /* 1.0 */
+  0
+}
+mysql_declare_plugin_end;
+
+#endif
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index 129a44b5721..f4fc5f47193 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -351,9 +351,13 @@
 #pragma implementation                          // gcc: Class implementation
 #endif
 
+#ifdef WITH_FEDERATED_STORAGE_ENGINE
 #include "ha_federated.h"
 
 #include "m_string.h"
+
+#include 
+
 /* Variables for federated share methods */
 static HASH federated_open_tables;              // To track open tables
 pthread_mutex_t federated_mutex;                // To init the hash
@@ -366,11 +370,14 @@ static int federated_rollback(THD *thd, bool all);
 
 /* Federated storage engine handlerton */
 
+static const char federated_hton_name[]= "FEDERATED";
+static const char federated_hton_comment[]= "Federated MySQL storage engine";
+
 handlerton federated_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "FEDERATED",
+  federated_hton_name,
   SHOW_OPTION_YES,
-  "Federated MySQL storage engine", 
+  federated_hton_comment, 
   DB_TYPE_FEDERATED_DB,
   federated_db_init,
   0,       /* slot */
@@ -2804,3 +2811,18 @@ int ha_federated::execute_simple_query(const char *query, int len)
   DBUG_RETURN(0);
 }
 
+
+mysql_declare_plugin(federated)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &federated_hton,
+  federated_hton_name,
+  "Patrick Galbraith and Brian Aker, MySQL AB",
+  federated_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+}
+mysql_declare_plugin_end;
+
+#endif
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index f20dfe259fb..1a7efb42748 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -26,11 +26,15 @@
 
 static handler *heap_create_handler(TABLE_SHARE *table);
 
+static const char heap_hton_name[]= "MEMORY";
+static const char heap_hton_comment[]=
+  "Hash based, stored in memory, useful for temporary tables";
+
 handlerton heap_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "MEMORY",
+  heap_hton_name,
   SHOW_OPTION_YES,
-  "Hash based, stored in memory, useful for temporary tables", 
+  heap_hton_comment,
   DB_TYPE_HEAP,
   NULL,
   0,       /* slot */
@@ -706,3 +710,17 @@ bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
     return COMPATIBLE_DATA_NO;
   return COMPATIBLE_DATA_YES;
 }
+
+mysql_declare_plugin(heap)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &heap_hton,
+  heap_hton_name,
+  "MySQL AB",
+  heap_hton_comment,
+  NULL,
+  NULL,
+  0x0100, /* 1.0 */
+  0
+}
+mysql_declare_plugin_end;
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 42def845174..0b2f561e8c9 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -42,6 +42,7 @@ have disables the InnoDB inlining in this file. */
 
 #define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
 
+#ifdef WITH_INNOBASE_STORAGE_ENGINE
 #include "ha_innodb.h"
 
 pthread_mutex_t innobase_share_mutex,	/* to protect innobase_open_files */
@@ -204,11 +205,15 @@ static int innobase_savepoint(THD* thd, void *savepoint);
 static int innobase_release_savepoint(THD* thd, void *savepoint);
 static handler *innobase_create_handler(TABLE_SHARE *table);
 
+static const char innobase_hton_name[]= "InnoDB";
+static const char innobase_hton_comment[]=
+  "Supports transactions, row-level locking, and foreign keys";
+
 handlerton innobase_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "InnoDB",
+  innobase_hton_name,
   SHOW_OPTION_YES,
-  "Supports transactions, row-level locking, and foreign keys",
+  innobase_hton_comment,
   DB_TYPE_INNODB,
   innobase_init,
   0,				/* slot */
@@ -5827,34 +5832,55 @@ ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list)
 			  break;
 	  }
 
-	  ulong length= 0;
-	  if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
-		  length=17;
-		  tmp_buff= "ON DELETE CASCADE";
-	  }
-	  else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
-		  length=18;
-		  tmp_buff= "ON DELETE SET NULL";
-	  }
-	  else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) {
-		  length=19;
-		  tmp_buff= "ON DELETE NO ACTION";
-	  }
-	  else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) {
-		  length=17;
-		  tmp_buff= "ON UPDATE CASCADE";
-	  }
-	  else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) {
-		  length=18;
-		  tmp_buff= "ON UPDATE SET NULL";
-	  }
-	  else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) {
-		  length=19;
-		  tmp_buff= "ON UPDATE NO ACTION";
-	  }
-	  f_key_info.constraint_method= make_lex_string(thd,
-		  f_key_info.constraint_method,
-		  tmp_buff, length, 1);
+          ulong length;
+          if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)
+          {
+            length=7;
+            tmp_buff= "CASCADE";
+          }	
+          else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
+          {
+            length=8;
+            tmp_buff= "SET NULL";
+          }
+          else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION)
+          {
+            length=9;
+            tmp_buff= "NO ACTION";
+          }
+          else
+          {
+            length=8;
+            tmp_buff= "RESTRICT";
+          }
+          f_key_info.delete_method= make_lex_string(thd, f_key_info.delete_method,
+                                                    tmp_buff, length, 1);
+ 
+ 
+          if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
+          {
+            length=7;
+            tmp_buff= "CASCADE";
+          }
+          else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
+          {
+            length=8;
+            tmp_buff= "SET NULL";
+          }
+          else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION)
+          {
+            length=9;
+            tmp_buff= "NO ACTION";
+          }
+          else
+          {
+            length=8;
+            tmp_buff= "RESTRICT";
+          }
+          f_key_info.update_method= make_lex_string(thd, f_key_info.update_method,
+                                                    tmp_buff, length, 1);
+
+
 
 	  FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *)
 		  thd->memdup((gptr) &f_key_info,
@@ -7432,3 +7458,20 @@ bool ha_innobase::check_if_incompatible_data(
 
 	return COMPATIBLE_DATA_YES;
 }
+
+
+mysql_declare_plugin(innobase)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &innobase_hton,
+  innobase_hton_name,
+  "Innobase OY",
+  innobase_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+  0
+}
+mysql_declare_plugin_end;
+
+#endif
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index ec39ee00efc..786d45a4966 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -31,6 +31,8 @@
 #include "../storage/myisam/rt_index.h"
 #endif
 
+#include 
+
 ulong myisam_recover_options= HA_RECOVER_NONE;
 
 /* bits in myisam_recover_options */
@@ -54,11 +56,15 @@ static handler *myisam_create_handler(TABLE_SHARE *table);
 
 /* MyISAM handlerton */
 
+static const char myisam_hton_name[]= "MyISAM";
+static const char myisam_hton_comment[]=
+  "Default engine as of MySQL 3.23 with great performance";
+
 handlerton myisam_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "MyISAM",
+  myisam_hton_name,
   SHOW_OPTION_YES,
-  "Default engine as of MySQL 3.23 with great performance", 
+  myisam_hton_comment, 
   DB_TYPE_MYISAM,
   NULL,
   0,       /* slot */
@@ -188,7 +194,7 @@ ha_myisam::ha_myisam(TABLE_SHARE *table_arg)
   int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
                   HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
                   HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME |
-                  HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD),
+                  HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS),
   can_enable_indexes(1)
 {}
 
@@ -350,6 +356,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
     if (table->key_info[i].flags & HA_USES_PARSER)
       file->s->keyinfo[i].parser=
         (struct st_mysql_ftparser *)parser->plugin->info;
+    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
   }
   return (0);
 }
@@ -1368,7 +1375,7 @@ void ha_myisam::info(uint flag)
     sortkey= info.sortkey;
     ref_length= info.reflength;
     share->db_options_in_use= info.options;
-    block_size= myisam_block_size;
+    block_size= myisam_block_size;		/* record block size */
 
     /* Update share */
     if (share->tmp_table == NO_TMP_TABLE)
@@ -1501,6 +1508,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
     keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? 
       (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
       pos->algorithm;
+    keydef[i].block_length= pos->block_size;
+
     keydef[i].seg=keyseg;
     keydef[i].keysegs=pos->key_parts;
     for (j=0 ; j < pos->key_parts ; j++)
@@ -1787,3 +1796,18 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
     return COMPATIBLE_DATA_NO;
   return COMPATIBLE_DATA_YES;
 }
+
+
+mysql_declare_plugin(myisam)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &myisam_hton,
+  myisam_hton_name,
+  "MySQL AB",
+  myisam_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100, /* 1.0 */
+  0
+}
+mysql_declare_plugin_end;
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 0ce4e1d8bcb..1cde37644bc 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -28,6 +28,8 @@
 #include "../storage/myisammrg/myrg_def.h"
 #endif
 
+#include 
+
 /*****************************************************************************
 ** MyISAM MERGE tables
 *****************************************************************************/
@@ -36,11 +38,15 @@ static handler *myisammrg_create_handler(TABLE_SHARE *table);
 
 /* MyISAM MERGE handlerton */
 
+static const char myisammrg_hton_name[]= "MRG_MYISAM";
+static const char myisammrg_hton_comment[]=
+  "Collection of identical MyISAM tables";
+
 handlerton myisammrg_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "MRG_MYISAM",
+  myisammrg_hton_name,
   SHOW_OPTION_YES,
-  "Collection of identical MyISAM tables", 
+  myisammrg_hton_comment, 
   DB_TYPE_MRG_MYISAM,
   NULL,
   0,       /* slot */
@@ -573,3 +579,17 @@ bool ha_myisammrg::check_if_incompatible_data(HA_CREATE_INFO *info,
   */
   return COMPATIBLE_DATA_NO;
 }
+
+mysql_declare_plugin(myisammrg)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &myisammrg_hton,
+  myisammrg_hton_name,
+  "MySQL AB",
+  myisammrg_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100, /* 1.0 */
+  0
+}
+mysql_declare_plugin_end;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 20844bf7e26..f0b4c2c3f6c 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -27,6 +27,7 @@
 #include "mysql_priv.h"
 
 #include 
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 #include "ha_ndbcluster.h"
 #include 
 #include 
@@ -36,6 +37,8 @@
 #include "ha_ndbcluster_binlog.h"
 #include "ha_ndbcluster_tables.h"
 
+#include 
+
 #ifdef ndb_dynamite
 #undef assert
 #define assert(x) do { if(x) break; ::printf("%s %d: assert failed: %s\n", __FILE__, __LINE__, #x); ::fflush(stdout); ::signal(SIGABRT,SIG_DFL); ::abort(); ::kill(::getpid(),6); ::kill(::getpid(),9); } while (0)
@@ -66,6 +69,9 @@ static bool ndbcluster_show_status(THD*,stat_print_fn *,enum ha_stat_type);
 static int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info);
 static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, COND *cond);
 
+static const char ndbcluster_hton_name[]= "ndbcluster";
+static const char ndbcluster_hton_comment[]= "Clustered, fault-tolerant tables";
+
 handlerton ndbcluster_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
   "ndbcluster",
@@ -141,7 +147,7 @@ static int rename_share(NDB_SHARE *share, const char *new_key);
 #endif
 static void ndb_set_fragmentation(NDBTAB &tab, TABLE *table, uint pk_len);
 
-static int ndb_get_table_statistics(Ndb*, const char *, 
+static int ndb_get_table_statistics(Ndb*, const NDBTAB *, 
                                     struct Ndb_statistics *);
 
 
@@ -431,7 +437,7 @@ void ha_ndbcluster::records_update()
     Ndb *ndb= get_ndb();
     ndb->setDatabaseName(m_dbname);
     struct Ndb_statistics stat;
-    if (ndb_get_table_statistics(ndb, m_tabname, &stat) == 0){
+    if (ndb_get_table_statistics(ndb, m_table, &stat) == 0){
       mean_rec_length= stat.row_size;
       data_file_length= stat.fragment_memory;
       info->records= stat.row_count;
@@ -479,92 +485,6 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
   DBUG_VOID_RETURN;
 }
 
-/*
-  Take care of the error that occured in NDB
-
-  RETURN
-    0   No error
-    #   The mapped error code
-*/
-
-int ha_ndbcluster::invalidate_dictionary_cache(bool global, const NDBTAB *ndbtab)
-{
-  NDBDICT *dict= get_ndb()->getDictionary();
-  DBUG_ENTER("invalidate_dictionary_cache");
-  DBUG_PRINT("info", ("m_tabname: %s  global: %d", m_tabname, global));
-
-  if (global)
-  {
-#ifdef HAVE_NDB_BINLOG
-    if (current_thd != injector_thd)
-    {
-      char key[FN_REFLEN];
-      build_table_filename(key, sizeof(key), m_dbname, m_tabname, "");
-      DBUG_PRINT("info", ("Getting ndbcluster mutex"));
-      pthread_mutex_lock(&ndbcluster_mutex);
-      NDB_SHARE *ndb_share= (NDB_SHARE*)hash_search(&ndbcluster_open_tables,
-                                                    (byte*) key, strlen(key));
-      // Only binlog_thread is allowed to globally invalidate a table
-      if (ndb_share && ndb_share->op)
-      {
-        pthread_mutex_unlock(&ndbcluster_mutex);
-        DBUG_PRINT("info", ("Released ndbcluster mutex"));
-        DBUG_RETURN(1);
-      }
-      pthread_mutex_unlock(&ndbcluster_mutex);
-      DBUG_PRINT("info", ("Released ndbcluster mutex"));
-    }
-#endif
-    if (!ndbtab)
-    {
-      ndbtab= dict->getTable(m_tabname);
-      if (!ndbtab)
-        DBUG_RETURN(1);
-    }
-    dict->invalidateTable(ndbtab);
-    table_share->version= 0L;			/* Free when thread is ready */
-  }
-  else if (ndbtab)
-    dict->removeCachedTable(ndbtab);
-  else
-    dict->removeCachedTable(m_tabname);
-
-  /* Invalidate indexes */
-  for (uint i= 0; i < table_share->keys; i++)
-  {
-    NDBINDEX *index = (NDBINDEX *) m_index[i].index;
-    NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
-    if (!index && !unique_index)
-      continue;
-    NDB_INDEX_TYPE idx_type= m_index[i].type;
-
-    switch (idx_type) {
-    case PRIMARY_KEY_ORDERED_INDEX:
-    case ORDERED_INDEX:
-      if (global)
-        dict->invalidateIndex(index->getName(), m_tabname);
-      else
-        dict->removeCachedIndex(index->getName(), m_tabname);
-      break;
-    case UNIQUE_ORDERED_INDEX:
-      if (global)
-        dict->invalidateIndex(index->getName(), m_tabname);
-      else
-        dict->removeCachedIndex(index->getName(), m_tabname);
-    case UNIQUE_INDEX:
-      if (global)
-        dict->invalidateIndex(unique_index->getName(), m_tabname);
-      else
-        dict->removeCachedIndex(unique_index->getName(), m_tabname);
-      break;
-    case PRIMARY_KEY_INDEX:
-    case UNDEFINED_INDEX:
-      break;
-    }
-  }
-  DBUG_RETURN(0);
-}
-
 int ha_ndbcluster::ndb_err(NdbTransaction *trans)
 {
   int res;
@@ -575,32 +495,14 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
   switch (err.classification) {
   case NdbError::SchemaError:
   {
+    // TODO perhaps we need to do more here, invalidate also in the cache
+    m_table->setStatusInvalid();
     /* Close other open handlers not used by any thread */
     TABLE_LIST table_list;
     bzero((char*) &table_list,sizeof(table_list));
     table_list.db= m_dbname;
     table_list.alias= table_list.table_name= m_tabname;
     close_cached_tables(current_thd, 0, &table_list);
-
-    invalidate_dictionary_cache(TRUE, m_table);
-
-    if (err.code==284)
-    {
-      /*
-         Check if the table is _really_ gone or if the table has
-         been alterend and thus changed table id
-       */
-      NDBDICT *dict= get_ndb()->getDictionary();
-      DBUG_PRINT("info", ("Check if table %s is really gone", m_tabname));
-      if (!(dict->getTable(m_tabname)))
-      {
-        err= dict->getNdbError();
-        DBUG_PRINT("info", ("Table not found, error: %d", err.code));
-        if (err.code != 709 && err.code != 723)
-          DBUG_RETURN(1);
-      }
-      DBUG_PRINT("info", ("Table exists but must have changed"));
-    }
     break;
   }
   default:
@@ -1046,73 +948,59 @@ int ha_ndbcluster::get_metadata(const char *path)
   NDBDICT *dict= ndb->getDictionary();
   const NDBTAB *tab;
   int error;
-  bool invalidating_ndb_table= FALSE;
   DBUG_ENTER("get_metadata");
   DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path));
 
-  do {
-    const void *data, *pack_data;
-    uint length, pack_length;
+  DBUG_ASSERT(m_table == NULL);
+  DBUG_ASSERT(m_table_info == NULL);
 
-    if (!(tab= dict->getTable(m_tabname)))
-      ERR_RETURN(dict->getNdbError());
-    // Check if thread has stale local cache
-    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
-    {
-      invalidate_dictionary_cache(FALSE, tab);
-      if (!(tab= dict->getTable(m_tabname)))
-         ERR_RETURN(dict->getNdbError());
-      DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
-    }
-    /*
-      Compare FrmData in NDB with frm file from disk.
-    */
-    error= 0;
-    if (readfrm(path, &data, &length) ||
-        packfrm(data, length, &pack_data, &pack_length))
-    {
-      my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
-      my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
-      DBUG_RETURN(1);
-    }
+  const void *data, *pack_data;
+  uint length, pack_length;
+
+  /*
+    Compare FrmData in NDB with frm file from disk.
+  */
+  error= 0;
+  if (readfrm(path, &data, &length) ||
+      packfrm(data, length, &pack_data, &pack_length))
+  {
+    my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
+    my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
+    DBUG_RETURN(1);
+  }
     
-    if (get_ndb_share_state(m_share) != NSS_ALTERED 
-        && cmp_frm(tab, pack_data, pack_length))
-    {
-      if (!invalidating_ndb_table)
-      {
-        DBUG_PRINT("info", ("Invalidating table"));
-        invalidate_dictionary_cache(TRUE, tab);
-        invalidating_ndb_table= TRUE;
-      }
-      else
-      {
-        DBUG_PRINT("error", 
-                   ("metadata, pack_length: %d  getFrmLength: %d  memcmp: %d",
-                    pack_length, tab->getFrmLength(),
-                    memcmp(pack_data, tab->getFrmData(), pack_length)));
-        DBUG_DUMP("pack_data", (char*)pack_data, pack_length);
-        DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength());
-        error= HA_ERR_TABLE_DEF_CHANGED;
-        invalidating_ndb_table= FALSE;
-      }
-    }
-    else
-    {
-      invalidating_ndb_table= FALSE;
-    }
-    my_free((char*)data, MYF(0));
-    my_free((char*)pack_data, MYF(0));
-  } while (invalidating_ndb_table);
+  Ndb_table_guard ndbtab_g(dict, m_tabname);
+  if (!(tab= ndbtab_g.get_table()))
+    ERR_RETURN(dict->getNdbError());
+
+  if (get_ndb_share_state(m_share) != NSS_ALTERED 
+      && cmp_frm(tab, pack_data, pack_length))
+  {
+    DBUG_PRINT("error", 
+               ("metadata, pack_length: %d  getFrmLength: %d  memcmp: %d",
+                pack_length, tab->getFrmLength(),
+                memcmp(pack_data, tab->getFrmData(), pack_length)));
+    DBUG_DUMP("pack_data", (char*)pack_data, pack_length);
+    DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength());
+    error= HA_ERR_TABLE_DEF_CHANGED;
+  }
+  my_free((char*)data, MYF(0));
+  my_free((char*)pack_data, MYF(0));
 
   if (error)
-    DBUG_RETURN(error);
-  
-  m_table_version= tab->getObjectVersion();
-  m_table= tab; 
-  m_table_info= NULL; // Set in external lock
-  
-  DBUG_RETURN(open_indexes(ndb, table, FALSE));
+    goto err;
+
+  DBUG_PRINT("info", ("fetched table %s", tab->getName()));
+  m_table= tab;
+  if ((error= open_indexes(ndb, table, FALSE)) == 0)
+  {
+    ndbtab_g.release();
+    DBUG_RETURN(0);
+  }
+err:
+  ndbtab_g.invalidate();
+  m_table= NULL;
+  DBUG_RETURN(error);
 }
 
 static int fix_unique_index_attr_order(NDB_INDEX_DATA &data,
@@ -1149,36 +1037,6 @@ static int fix_unique_index_attr_order(NDB_INDEX_DATA &data,
   DBUG_RETURN(0);
 }
 
-int ha_ndbcluster::table_changed(const void *pack_frm_data, uint pack_frm_len)
-{
-  Ndb *ndb;
-  NDBDICT *dict;
-  const NDBTAB *orig_tab;
-  NdbDictionary::Table new_tab;
-  int result;
-  DBUG_ENTER("ha_ndbcluster::table_changed");
-  DBUG_PRINT("info", ("Modifying frm for table %s", m_tabname));
-  if (check_ndb_connection())
-    DBUG_RETURN(my_errno= HA_ERR_NO_CONNECTION);
-                                                                             
-  ndb= get_ndb();
-  dict= ndb->getDictionary();
-  if (!(orig_tab= dict->getTable(m_tabname)))
-    ERR_RETURN(dict->getNdbError());
-  // Check if thread has stale local cache
-  if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
-  {
-    dict->removeCachedTable(orig_tab);
-    if (!(orig_tab= dict->getTable(m_tabname)))
-      ERR_RETURN(dict->getNdbError());
-  }
-  new_tab= *orig_tab;
-  new_tab.setFrm(pack_frm_data, pack_frm_len);
-  if (dict->alterTable(new_tab) != 0)
-    ERR_RETURN(dict->getNdbError());
-  DBUG_RETURN(0);
-}
-
 /*
   Create all the indexes for a table.
   If any index should fail to be created,
@@ -1209,22 +1067,30 @@ int ha_ndbcluster::create_indexes(Ndb *ndb, TABLE *tab)
   DBUG_RETURN(error);
 }
 
-void ha_ndbcluster::clear_index(int i)
+static void ndb_init_index(NDB_INDEX_DATA &data)
 {
-  m_index[i].type= UNDEFINED_INDEX;
-  m_index[i].status= UNDEFINED;
-  m_index[i].unique_index= NULL;
-  m_index[i].index= NULL;
-  m_index[i].unique_index_attrid_map= NULL;
-  m_index[i].index_stat=NULL;
-  m_index[i].index_stat_cache_entries=0;
-  m_index[i].index_stat_update_freq=0;
-  m_index[i].index_stat_query_count=0;
+  data.type= UNDEFINED_INDEX;
+  data.status= UNDEFINED;
+  data.unique_index= NULL;
+  data.index= NULL;
+  data.unique_index_attrid_map= NULL;
+  data.index_stat=NULL;
+  data.index_stat_cache_entries=0;
+  data.index_stat_update_freq=0;
+  data.index_stat_query_count=0;
 }
 
-void ha_ndbcluster::clear_indexes()
+static void ndb_clear_index(NDB_INDEX_DATA &data)
 {
-  for (int i= 0; i < MAX_KEY; i++) clear_index(i);
+  if (data.unique_index_attrid_map)
+  {
+    my_free((char*)data.unique_index_attrid_map, MYF(0));
+  }
+  if (data.index_stat)
+  {
+    delete data.index_stat;
+  }
+  ndb_init_index(data);
 }
 
 /*
@@ -1246,7 +1112,7 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
     const NDBINDEX *index;
     do
     {
-      index= dict->getIndex(index_name, m_tabname);
+      index= dict->getIndexGlobal(index_name, *m_table);
       if (!index)
         ERR_RETURN(dict->getNdbError());
       DBUG_PRINT("info", ("index: 0x%x  id: %d  version: %d.%d  status: %d",
@@ -1255,14 +1121,11 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
                           index->getObjectVersion() & 0xFFFFFF,
                           index->getObjectVersion() >> 24,
                           index->getObjectStatus()));
-      if (index->getObjectStatus() != NdbDictionary::Object::Retrieved)
-      {
-        dict->removeCachedIndex(index);
-        continue;
-      }
+      DBUG_ASSERT(index->getObjectStatus() ==
+                  NdbDictionary::Object::Retrieved);
       break;
     } while (1);
-    m_index[index_no].index= (void *) index;
+    m_index[index_no].index= index;
     // ordered index - add stats
     NDB_INDEX_DATA& d=m_index[index_no];
     delete d.index_stat;
@@ -1293,7 +1156,7 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
     const NDBINDEX *index;
     do
     {
-      index= dict->getIndex(unique_index_name, m_tabname);
+      index= dict->getIndexGlobal(unique_index_name, *m_table);
       if (!index)
         ERR_RETURN(dict->getNdbError());
       DBUG_PRINT("info", ("index: 0x%x  id: %d  version: %d.%d  status: %d",
@@ -1302,14 +1165,11 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
                           index->getObjectVersion() & 0xFFFFFF,
                           index->getObjectVersion() >> 24,
                           index->getObjectStatus()));
-      if (index->getObjectStatus() != NdbDictionary::Object::Retrieved)
-      {
-        dict->removeCachedIndex(index);
-        continue;
-      }
+      DBUG_ASSERT(index->getObjectStatus() ==
+                  NdbDictionary::Object::Retrieved);
       break;
     } while (1);
-    m_index[index_no].unique_index= (void *) index;
+    m_index[index_no].unique_index= index;
     error= fix_unique_index_attr_order(m_index[index_no], index, key_info);
   }
   if (!error)
@@ -1340,7 +1200,27 @@ int ha_ndbcluster::open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error)
       else
         break;
   }
-  
+
+  if (error && !ignore_error)
+  {
+    while (i > 0)
+    {
+      i--;
+      if (m_index[i].index)
+      {
+         dict->removeIndexGlobal(*m_index[i].index, 1);
+         m_index[i].index= NULL;
+      }
+      if (m_index[i].unique_index)
+      {
+         dict->removeIndexGlobal(*m_index[i].unique_index, 1);
+         m_index[i].unique_index= NULL;
+      }
+    }
+  }
+
+  DBUG_ASSERT(error == 0 || error == 4243);
+
   DBUG_RETURN(error);
 }
 
@@ -1400,30 +1280,36 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab)
     m_index[i].type= idx_type;
     if (m_index[i].status == TO_BE_DROPPED)
     {
-      NdbDictionary::Index *index= 
-        (NdbDictionary::Index *) m_index[i].index;
-      NdbDictionary::Index *unique_index= 
-        (NdbDictionary::Index *) m_index[i].unique_index;
+      const NdbDictionary::Index *index= m_index[i].index;
+      const NdbDictionary::Index *unique_index= m_index[i].unique_index;
       
       if (index)
       {
         index_name= index->getName();
         DBUG_PRINT("info", ("Dropping index %u: %s", i, index_name));  
         // Drop ordered index from ndb
-        error= drop_ndb_index(index_name);
+        error= dict->dropIndexGlobal(*index);
+        if (!error)
+        {
+          dict->removeIndexGlobal(*index, 1);
+          m_index[i].index= NULL;
+        }
       }
-      if (!error)
-        m_index[i].index= NULL;
       if (!error && unique_index)
       {
         index_name= unique_index->getName();
         DBUG_PRINT("info", ("Dropping unique index %u: %s", i, index_name));
         // Drop unique index from ndb
-        error= drop_ndb_index(index_name);
+        error= dict->dropIndexGlobal(*unique_index);
+        if (!error)
+        {
+          dict->removeIndexGlobal(*unique_index, 1);
+          m_index[i].unique_index= NULL;
+        }
       }
       if (error)
         DBUG_RETURN(error);
-      clear_index(i);
+      ndb_clear_index(m_index[i]);
       continue;
     }
   }
@@ -1476,30 +1362,46 @@ int ha_ndbcluster::check_index_fields_not_null(uint inx)
   DBUG_RETURN(0);
 }
 
-void ha_ndbcluster::release_metadata()
+void ha_ndbcluster::release_metadata(THD *thd, Ndb *ndb)
 {
   uint i;
 
   DBUG_ENTER("release_metadata");
   DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
 
-  m_table= NULL;
+  NDBDICT *dict= ndb->getDictionary();
+  int invalidate_indexes= 0;
+  if (thd && thd->lex && thd->lex->sql_command == SQLCOM_FLUSH)
+  {
+    invalidate_indexes = 1;
+  }
+  if (m_table != NULL)
+  {
+    if (m_table->getObjectStatus() == NdbDictionary::Object::Invalid)
+      invalidate_indexes= 1;
+    dict->removeTableGlobal(*m_table, invalidate_indexes);
+  }
+  // TODO investigate
+  DBUG_ASSERT(m_table_info == NULL);
   m_table_info= NULL;
 
   // Release index list 
   for (i= 0; i < MAX_KEY; i++)
   {
-    m_index[i].unique_index= NULL;      
-    m_index[i].index= NULL;      
-    if (m_index[i].unique_index_attrid_map)
+    if (m_index[i].unique_index)
     {
-      my_free((char *)m_index[i].unique_index_attrid_map, MYF(0));
-      m_index[i].unique_index_attrid_map= NULL;
+      DBUG_ASSERT(m_table != NULL);
+      dict->removeIndexGlobal(*m_index[i].unique_index, invalidate_indexes);
     }
-    delete m_index[i].index_stat;
-    m_index[i].index_stat=NULL;
+    if (m_index[i].index)
+    {
+      DBUG_ASSERT(m_table != NULL);
+      dict->removeIndexGlobal(*m_index[i].index, invalidate_indexes);
+    }
+    ndb_clear_index(m_index[i]);
   }
 
+  m_table= NULL;
   DBUG_VOID_RETURN;
 }
 
@@ -1971,11 +1873,10 @@ int ha_ndbcluster::peek_indexed_rows(const byte *record)
     {
       // A unique index is defined on table
       NdbIndexOperation *iop;
-      NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
+      const NDBINDEX *unique_index = m_index[i].unique_index;
       key_part= key_info->key_part;
       end= key_part + key_info->key_parts;
-      if (!(iop= trans->getNdbIndexOperation(unique_index,
-                                             (const NDBTAB *) m_table)) ||
+      if (!(iop= trans->getNdbIndexOperation(unique_index, m_table)) ||
           iop->readTuple(lm) != 0)
         ERR_RETURN(trans->getNdbError());
 
@@ -2024,9 +1925,8 @@ int ha_ndbcluster::unique_index_read(const byte *key,
   
   NdbOperation::LockMode lm=
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
-  if (!(op= trans->getNdbIndexOperation((NDBINDEX *) 
-                                        m_index[active_index].unique_index, 
-                                        (const NDBTAB *) m_table)) ||
+  if (!(op= trans->getNdbIndexOperation(m_index[active_index].unique_index, 
+                                        m_table)) ||
       op->readTuple(lm) != 0)
     ERR_RETURN(trans->getNdbError());
   
@@ -2365,9 +2265,8 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key,
     restart= FALSE;
     NdbOperation::LockMode lm=
       (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
-    if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *)
-                                              m_index[active_index].index, 
-                                              (const NDBTAB *) m_table)) ||
+    if (!(op= trans->getNdbIndexScanOperation(m_index[active_index].index, 
+                                              m_table)) ||
         op->readTuples(lm, 0, parallelism, sorted, descending))
       ERR_RETURN(trans->getNdbError());
     if (m_use_partition_function && part_spec != NULL &&
@@ -2437,7 +2336,7 @@ int ha_ndbcluster::full_table_scan(byte *buf)
 
   NdbOperation::LockMode lm=
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
-  if (!(op=trans->getNdbScanOperation((const NDBTAB *) m_table)) ||
+  if (!(op=trans->getNdbScanOperation(m_table)) ||
       op->readTuples(lm, 0, parallelism))
     ERR_RETURN(trans->getNdbError());
   m_active_cursor= op;
@@ -2539,7 +2438,7 @@ int ha_ndbcluster::write_row(byte *record)
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
     table->timestamp_field->set_time();
 
-  if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)))
+  if (!(op= trans->getNdbOperation(m_table)))
     ERR_RETURN(trans->getNdbError());
 
   res= (m_use_write) ? op->writeTuple() :op->insertTuple(); 
@@ -2565,7 +2464,7 @@ int ha_ndbcluster::write_row(byte *record)
     Uint64 auto_value= NDB_FAILED_AUTO_INCREMENT;
     uint retries= NDB_AUTO_INCREMENT_RETRIES;
     do {
-      auto_value= ndb->getAutoIncrementValue((const NDBTAB *) m_table);
+      auto_value= ndb->getAutoIncrementValue(m_table);
     } while (auto_value == NDB_FAILED_AUTO_INCREMENT && 
              --retries &&
              ndb->getNdbError().status == NdbError::TemporaryError);
@@ -2666,7 +2565,7 @@ int ha_ndbcluster::write_row(byte *record)
     DBUG_PRINT("info", 
                ("Trying to set next auto increment value to %lu",
                 (ulong) next_val));
-    if (ndb->setAutoIncrementValue((const NDBTAB *) m_table, next_val, TRUE))
+    if (ndb->setAutoIncrementValue(m_table, next_val, TRUE))
       DBUG_PRINT("info", 
                  ("Setting next auto increment value to %u", next_val));  
   }
@@ -2816,7 +2715,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
   }
   else
   {  
-    if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) ||
+    if (!(op= trans->getNdbOperation(m_table)) ||
         op->updateTuple() != 0)
       ERR_RETURN(trans->getNdbError());  
     
@@ -2925,7 +2824,7 @@ int ha_ndbcluster::delete_row(const byte *record)
   else
   {
     
-    if (!(op=trans->getNdbOperation((const NDBTAB *) m_table)) || 
+    if (!(op=trans->getNdbOperation(m_table)) || 
         op->deleteTuple() != 0)
       ERR_RETURN(trans->getNdbError());
     
@@ -3078,7 +2977,7 @@ void ha_ndbcluster::unpack_record(byte *buf)
   {
     // Table with hidden primary key
     int hidden_no= table_share->fields;
-    const NDBTAB *tab= (const NDBTAB *) m_table;
+    const NDBTAB *tab= m_table;
     const NDBCOL *hidden_col= tab->getColumn(hidden_no);
     const NdbRecAttr* rec= m_value[hidden_no].rec;
     DBUG_ASSERT(rec);
@@ -3554,7 +3453,7 @@ void ha_ndbcluster::position(const byte *record)
       key_length= ref_length;
 #ifndef DBUG_OFF
     int hidden_no= table->s->fields;
-    const NDBTAB *tab= (const NDBTAB *) m_table;  
+    const NDBTAB *tab= m_table;  
     const NDBCOL *hidden_col= tab->getColumn(hidden_no);
     DBUG_ASSERT(hidden_col->getPrimaryKey() && 
                 hidden_col->getAutoIncrement() &&
@@ -3600,7 +3499,7 @@ void ha_ndbcluster::info(uint flag)
       ndb->setDatabaseName(m_dbname);
       struct Ndb_statistics stat;
       if (current_thd->variables.ndb_use_exact_count &&
-          ndb_get_table_statistics(ndb, m_tabname, &stat) == 0)
+          ndb_get_table_statistics(ndb, m_table, &stat) == 0)
       {
         mean_rec_length= stat.row_size;
         data_file_length= stat.fragment_memory;
@@ -3631,7 +3530,7 @@ void ha_ndbcluster::info(uint flag)
       Ndb *ndb= get_ndb();
       
       auto_increment_value= 
-        ndb->readAutoIncrementValue((const NDBTAB *) m_table);
+        ndb->readAutoIncrementValue(m_table);
     }
   }
   DBUG_VOID_RETURN;
@@ -3715,7 +3614,7 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
 void ha_ndbcluster::start_bulk_insert(ha_rows rows)
 {
   int bytes, batch;
-  const NDBTAB *tab= (const NDBTAB *) m_table;    
+  const NDBTAB *tab= m_table;    
 
   DBUG_ENTER("start_bulk_insert");
   DBUG_PRINT("enter", ("rows: %d", (int)rows));
@@ -3994,41 +3893,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
     // Start of transaction
     m_rows_changed= 0;
     m_ops_pending= 0;
-    {
-      NDBDICT *dict= ndb->getDictionary();
-      const NDBTAB *tab;
-      if (!(tab= dict->getTable(m_tabname)))
-        ERR_RETURN(dict->getNdbError());
-      DBUG_PRINT("info", ("Table schema version: %d", 
-                          tab->getObjectVersion()));
-      // Check if thread has stale local cache
-      // New transaction must not use old tables... (trans != 0)
-      // Running might...
-      if ((trans && tab->getObjectStatus() != NdbDictionary::Object::Retrieved)
-	  || tab->getObjectStatus() == NdbDictionary::Object::Invalid)
-      {
-        invalidate_dictionary_cache(FALSE, tab);
-        if (!(tab= dict->getTable(m_tabname)))
-          ERR_RETURN(dict->getNdbError());
-        DBUG_PRINT("info", ("Table schema version: %d", 
-                            tab->getObjectVersion()));
-      }
-      if (m_table_version < tab->getObjectVersion())
-      {
-        /*
-          The table has been altered, caller has to retry
-        */
-        NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT);
-        DBUG_RETURN(ndb_to_mysql_error(&err));
-      }
-      if (m_table != (void *)tab)
-      {
-        m_table= tab;
-        m_table_version = tab->getObjectVersion();
-        if (!(my_errno= open_indexes(ndb, table, FALSE)))
-          DBUG_RETURN(my_errno);
-      }
-    }
+
+    // TODO remove double pointers...
     m_thd_ndb_share= thd_ndb->get_open_table(thd, m_table);
     m_table_info= &m_thd_ndb_share->stat;
   }
@@ -4673,6 +4539,14 @@ int ha_ndbcluster::create(const char *name,
     my_errno= ndb_to_mysql_error(&err);
     DBUG_RETURN(my_errno);
   }
+
+  Ndb_table_guard ndbtab_g(dict, m_tabname);
+  // temporary set m_table during create
+  // reset at return
+  m_table= ndbtab_g.get_table();
+  // TODO check also that we have the same frm...
+  DBUG_ASSERT(m_table != 0);
+
   DBUG_PRINT("info", ("Table %s/%s created successfully", 
                       m_dbname, m_tabname));
 
@@ -4687,7 +4561,10 @@ int ha_ndbcluster::create(const char *name,
       Failed to create an index,
       drop the table (and all it's indexes)
     */
-    drop_ndb_table();
+    if (dict->dropTableGlobal(*m_table) == 0)
+    {
+      m_table = 0;
+    }
   }
 
 #ifdef HAVE_NDB_BINLOG
@@ -4717,7 +4594,6 @@ int ha_ndbcluster::create(const char *name,
 
     while (!IS_TMP_PREFIX(m_tabname))
     {
-      const NDBTAB *t= dict->getTable(m_tabname);
       String event_name(INJECTOR_EVENT_LEN);
       ndb_rep_event_name(&event_name,m_dbname,m_tabname);
       int do_event_op= ndb_binlog_running;
@@ -4731,14 +4607,14 @@ int ha_ndbcluster::create(const char *name,
         Always create an event for the table, as other mysql servers
         expect it to be there.
       */
-      if (!ndbcluster_create_event(ndb, t, event_name.c_ptr(), share,
+      if (!ndbcluster_create_event(ndb, m_table, event_name.c_ptr(), share,
                                    share && do_event_op /* push warning */))
       {
         if (ndb_extra_logging)
           sql_print_information("NDB Binlog: CREATE TABLE Event: %s",
                                 event_name.c_ptr());
         if (share && do_event_op &&
-            ndbcluster_create_event_ops(share, t, event_name.c_ptr()))
+            ndbcluster_create_event_ops(share, m_table, event_name.c_ptr()))
         {
           sql_print_error("NDB Binlog: FAILED CREATE TABLE event operations."
                           " Event: %s", name);
@@ -4754,13 +4630,15 @@ int ha_ndbcluster::create(const char *name,
       ndbcluster_log_schema_op(current_thd, share,
                                current_thd->query, current_thd->query_length,
                                share->db, share->table_name,
-                               0, 0,
+                               m_table->getObjectId(),
+                               m_table->getObjectVersion(),
                                SOT_CREATE_TABLE);
       break;
     }
   }
 #endif /* HAVE_NDB_BINLOG */
 
+  m_table= 0;
   DBUG_RETURN(my_errno);
 }
 
@@ -4790,10 +4668,15 @@ int ha_ndbcluster::create_handler_files(const char *file,
   NDBDICT *dict= ndb->getDictionary();
   if (!info->frm_only)
     DBUG_RETURN(0); // Must be a create, ignore since frm is saved in create
+
+  // TODO handle this
+  DBUG_ASSERT(m_table != 0);
+
   set_dbname(file);
   set_tabname(file);
+  Ndb_table_guard ndbtab_g(dict, m_tabname);
   DBUG_PRINT("info", ("m_dbname: %s, m_tabname: %s", m_dbname, m_tabname));
-  if (!(tab= dict->getTable(m_tabname)))
+  if (!(tab= ndbtab_g.get_table()))
     DBUG_RETURN(0); // Unkown table, must be temporary table
 
   DBUG_ASSERT(get_ndb_share_state(m_share) == NSS_ALTERED);
@@ -4809,7 +4692,12 @@ int ha_ndbcluster::create_handler_files(const char *file,
   {
     DBUG_PRINT("info", ("Table %s has changed, altering frm in ndb", 
                         m_tabname));
-    error= table_changed(pack_data, pack_length);
+    NdbDictionary::Table new_tab= *tab;
+    new_tab.setFrm(pack_data, pack_length);
+    if (dict->alterTableGlobal(*tab, new_tab))
+    {
+      error= ndb_to_mysql_error(&dict->getNdbError());
+    }
     my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
     my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
   }
@@ -4912,7 +4800,7 @@ int ha_ndbcluster::create_ndb_index(const char *name,
     ndb_index.addColumnName(field->field_name);
   }
   
-  if (dict->createIndex(ndb_index))
+  if (dict->createIndex(ndb_index, *m_table))
     ERR_RETURN(dict->getNdbError());
 
   // Success
@@ -4965,18 +4853,6 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
   DBUG_RETURN(error);  
 }
 
-/*
-  Drop an index in ndb
- */
-int ha_ndbcluster::drop_ndb_index(const char *name)
-{
-  DBUG_ENTER("ha_ndbcluster::drop_index");
-  DBUG_PRINT("enter", ("name: %s ", name));
-  Ndb *ndb= get_ndb();
-  NdbDictionary::Dictionary *dict= ndb->getDictionary();
-  DBUG_RETURN(dict->dropIndex(name, m_tabname));
-} 
-
 /*
   Mark one or several indexes for deletion. and
   renumber the remaining indexes
@@ -5045,16 +4921,14 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
   Ndb *ndb= get_ndb();
   ndb->setDatabaseName(old_dbname);
   dict= ndb->getDictionary();
-  if (!(orig_tab= dict->getTable(m_tabname)))
+  Ndb_table_guard ndbtab_g(dict, m_tabname);
+  if (!(orig_tab= ndbtab_g.get_table()))
     ERR_RETURN(dict->getNdbError());
-  // Check if thread has stale local cache
-  if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
-  {
-    dict->removeCachedTable(orig_tab);
-    if (!(orig_tab= dict->getTable(m_tabname)))
-      ERR_RETURN(dict->getNdbError());
-  }
+
 #ifdef HAVE_NDB_BINLOG
+  int ndb_table_id= orig_tab->getObjectId();
+  int ndb_table_version= orig_tab->getObjectVersion();
+
   NDB_SHARE *share= get_share(from, 0, false);
   if (share)
   {
@@ -5062,13 +4936,15 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
     DBUG_ASSERT(r == 0);
   }
 #endif
-  m_table= orig_tab;
   // Change current database to that of target table
   set_dbname(to);
   ndb->setDatabaseName(m_dbname);
 
-  if ((result= alter_table_name(new_tabname)))
+  NdbDictionary::Table new_tab= *orig_tab;
+  new_tab.setName(new_tabname);
+  if (dict->alterTableGlobal(*orig_tab, new_tab) != 0)
   {
+    NdbError ndb_error= dict->getNdbError();
 #ifdef HAVE_NDB_BINLOG
     if (share)
     {
@@ -5077,7 +4953,7 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
       free_share(&share);
     }
 #endif
-    DBUG_RETURN(result);
+    ERR_RETURN(ndb_error);
   }
   
   // Rename .ndb file
@@ -5111,7 +4987,8 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
     /* always create an event for the table */
     String event_name(INJECTOR_EVENT_LEN);
     ndb_rep_event_name(&event_name, to + sizeof(share_prefix) - 1, 0);
-    const NDBTAB *ndbtab= dict->getTable(new_tabname);
+    Ndb_table_guard ndbtab_g2(dict, new_tabname);
+    const NDBTAB *ndbtab= ndbtab_g2.get_table();
 
     if (!ndbcluster_create_event(ndb, ndbtab, event_name.c_ptr(), share,
                                  share && ndb_binlog_running /* push warning */))
@@ -5134,10 +5011,10 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
     if (!is_old_table_tmpfile)
       ndbcluster_log_schema_op(current_thd, share,
                                current_thd->query, current_thd->query_length,
-                               m_dbname, new_tabname,
-                               0, 0,
+                               old_dbname, m_tabname,
+                               ndb_table_id, ndb_table_version,
                                SOT_RENAME_TABLE,
-                               old_dbname, m_tabname);
+                               m_dbname, new_tabname);
   }
   if (share)
     free_share(&share);
@@ -5147,30 +5024,6 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
 }
 
 
-/*
-  Rename a table in NDB Cluster using alter table
- */
-
-int ha_ndbcluster::alter_table_name(const char *to)
-{
-  Ndb *ndb= get_ndb();
-  NDBDICT *dict= ndb->getDictionary();
-  const NDBTAB *orig_tab= (const NDBTAB *) m_table;
-  DBUG_ENTER("alter_table_name");
-  DBUG_PRINT("info", ("from: %s to: %s", orig_tab->getName(), to));
-
-  NdbDictionary::Table new_tab= *orig_tab;
-  new_tab.setName(to);
-  if (dict->alterTable(new_tab) != 0)
-    ERR_RETURN(dict->getNdbError());
-
-  m_table= NULL;
-  m_table_info= NULL;
-                                                                             
-  DBUG_RETURN(0);
-}
-
-
 /*
   Delete table from NDB Cluster
 
@@ -5187,6 +5040,8 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
   DBUG_ENTER("ha_ndbcluster::ndbcluster_delete_table");
   NDBDICT *dict= ndb->getDictionary();
 #ifdef HAVE_NDB_BINLOG
+  int ndb_table_id= 0;
+  int ndb_table_version= 0;
   /*
     Don't allow drop table unless
     schema distribution table is setup
@@ -5202,14 +5057,45 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
   /* Drop the table from NDB */
   
   int res;
-  if (h)
+  if (h && h->m_table)
   {
-    res= h->drop_ndb_table();
+    if (dict->dropTableGlobal(*h->m_table))
+      res= ndb_to_mysql_error(&dict->getNdbError());
+#ifdef HAVE_NDB_BINLOG
+    if (res == 0)
+    {
+      ndb_table_id= h->m_table->getObjectId();
+      ndb_table_version= h->m_table->getObjectVersion();
+    }
+#endif
+    h->release_metadata(current_thd, ndb);
   }
   else
   {
     ndb->setDatabaseName(db);
-    res= dict->dropTable(table_name);
+    while (1)
+    {
+      Ndb_table_guard ndbtab_g(dict, table_name);
+      if (ndbtab_g.get_table())
+      {
+        if (dict->dropTableGlobal(*ndbtab_g.get_table()) == 0)
+        {
+#ifdef HAVE_NDB_BINLOG
+          ndb_table_id= ndbtab_g.get_table()->getObjectId();
+          ndb_table_version= ndbtab_g.get_table()->getObjectVersion();
+#endif
+          res= 0;
+        }
+        else if (dict->getNdbError().code == NDB_INVALID_SCHEMA_OBJECT)
+        {
+          ndbtab_g.invalidate();
+          continue;
+        }
+      }
+      else
+        res= ndb_to_mysql_error(&dict->getNdbError());
+      break;
+    }
   }
 
   if (res)
@@ -5251,7 +5137,7 @@ ha_ndbcluster::delete_table(ha_ndbcluster *h, Ndb *ndb,
     ndbcluster_log_schema_op(current_thd, share,
                              current_thd->query, current_thd->query_length,
                              share->db, share->table_name,
-                             0, 0,
+                             ndb_table_id, ndb_table_version,
                              SOT_DROP_TABLE);
   }
   else if (table_dropped && share && share->op) /* ndbcluster_log_schema_op
@@ -5315,24 +5201,6 @@ int ha_ndbcluster::delete_table(const char *name)
 }
 
 
-/*
-  Drop table in NDB Cluster
- */
-
-int ha_ndbcluster::drop_ndb_table()
-{
-  Ndb *ndb= get_ndb();
-  NdbDictionary::Dictionary *dict= ndb->getDictionary();
-
-  DBUG_ENTER("intern_drop_table");
-  DBUG_PRINT("enter", ("Deleting %s", m_tabname));
-  release_metadata();
-  if (dict->dropTable(m_tabname))
-    ERR_RETURN(dict->getNdbError());
-  DBUG_RETURN(0);
-}
-
-
 ulonglong ha_ndbcluster::get_auto_increment()
 {  
   int cache_size;
@@ -5356,8 +5224,8 @@ ulonglong ha_ndbcluster::get_auto_increment()
   do {
     auto_value=
       (m_skip_auto_increment) ? 
-      ndb->readAutoIncrementValue((const NDBTAB *) m_table)
-      : ndb->getAutoIncrementValue((const NDBTAB *) m_table, cache_size);
+      ndb->readAutoIncrementValue(m_table)
+      : ndb->getAutoIncrementValue(m_table, cache_size);
   } while (auto_value == NDB_FAILED_AUTO_INCREMENT && 
            --retries &&
            ndb->getNdbError().status == NdbError::TemporaryError);
@@ -5391,7 +5259,6 @@ ha_ndbcluster::ha_ndbcluster(TABLE_SHARE *table_arg):
   m_active_trans(NULL),
   m_active_cursor(NULL),
   m_table(NULL),
-  m_table_version(-1),
   m_table_info(NULL),
   m_table_flags(HA_NDBCLUSTER_TABLE_FLAGS),
   m_share(0),
@@ -5431,25 +5298,38 @@ ha_ndbcluster::ha_ndbcluster(TABLE_SHARE *table_arg):
   records= ~(ha_rows)0; // uninitialized
   block_size= 1024;
 
-  clear_indexes();
+  for (i= 0; i < MAX_KEY; i++)
+    ndb_init_index(m_index[i]);
 
   DBUG_VOID_RETURN;
 }
 
 
+int ha_ndbcluster::ha_initialise()
+{
+  DBUG_ENTER("ha_ndbcluster::ha_initialise");
+  if (check_ndb_in_thd(current_thd))
+  {
+    DBUG_RETURN(FALSE);
+  }
+  DBUG_RETURN(TRUE);
+}
+
 /*
   Destructor for NDB Cluster table handler
  */
 
 ha_ndbcluster::~ha_ndbcluster() 
 {
+  THD *thd= current_thd;
+  Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
   DBUG_ENTER("~ha_ndbcluster");
 
   if (m_share)
   {
     free_share(&m_share);
   }
-  release_metadata();
+  release_metadata(thd, ndb);
   my_free(m_blobs_buffer, MYF(MY_ALLOW_ZERO_PTR));
   m_blobs_buffer= 0;
 
@@ -5564,10 +5444,12 @@ void ha_ndbcluster::set_part_info(partition_info *part_info)
 
 int ha_ndbcluster::close(void)
 {
-  DBUG_ENTER("close");  
+  DBUG_ENTER("close");
+  THD *thd= current_thd;
+  Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
   free_share(&m_share);
   m_share= 0;
-  release_metadata();
+  release_metadata(thd, ndb);
   DBUG_RETURN(0);
 }
 
@@ -5655,9 +5537,10 @@ static int ndbcluster_close_connection(THD *thd)
 int ndbcluster_discover(THD* thd, const char *db, const char *name,
                         const void** frmblob, uint* frmlen)
 {
+  int error= 0;
+  NdbError ndb_error;
   uint len;
   const void* data;
-  const NDBTAB* tab;
   Ndb* ndb;
   char key[FN_REFLEN];
   DBUG_ENTER("ndbcluster_discover");
@@ -5667,7 +5550,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
     DBUG_RETURN(HA_ERR_NO_CONNECTION);  
   ndb->setDatabaseName(db);
   NDBDICT* dict= ndb->getDictionary();
-  dict->invalidateTable(name);
   build_table_filename(key, sizeof(key), db, name, "");
   NDB_SHARE *share= get_share(key, 0, false);
   if (share && get_ndb_share_state(share) == NSS_ALTERED)
@@ -5676,21 +5558,22 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
     if (readfrm(key, &data, &len))
     {
       DBUG_PRINT("error", ("Could not read frm"));
-      if (share)
-        free_share(&share);
-      DBUG_RETURN(1);
+      error= 1;
+      goto err;
     }
   }
   else
   {
-    if (!(tab= dict->getTable(name)))
-    {    
+    Ndb_table_guard ndbtab_g(dict, name);
+    const NDBTAB *tab= ndbtab_g.get_table();
+    if (!tab)
+    {
       const NdbError err= dict->getNdbError();
-      if (share)
-        free_share(&share);
       if (err.code == 709 || err.code == 723)
-        DBUG_RETURN(-1);
-      ERR_RETURN(err);
+        error= -1;
+      else
+        ndb_error= err;
+      goto err;
     }
     DBUG_PRINT("info", ("Found table %s", tab->getName()));
     
@@ -5698,17 +5581,15 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
     if (len == 0 || tab->getFrmData() == NULL)
     {
       DBUG_PRINT("error", ("No frm data found."));
-      if (share)
-        free_share(&share);
-      DBUG_RETURN(1);
+      error= 1;
+      goto err;
     }
     
     if (unpackfrm(&data, &len, tab->getFrmData()))
     {
       DBUG_PRINT("error", ("Could not unpack table"));
-      if (share)
-        free_share(&share);
-      DBUG_RETURN(1);
+      error= 1;
+      goto err;
     }
   }
 
@@ -5719,6 +5600,14 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
     free_share(&share);
 
   DBUG_RETURN(0);
+err:
+  if (share)
+    free_share(&share);
+  if (ndb_error.code)
+  {
+    ERR_RETURN(ndb_error);
+  }
+  DBUG_RETURN(error);
 }
 
 /*
@@ -5726,29 +5615,32 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
 
  */
 
-int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name)
+int ndbcluster_table_exists_in_engine(THD* thd, const char *db,
+                                      const char *name)
 {
-  const NDBTAB* tab;
   Ndb* ndb;
   DBUG_ENTER("ndbcluster_table_exists_in_engine");
   DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
 
   if (!(ndb= check_ndb_in_thd(thd)))
     DBUG_RETURN(HA_ERR_NO_CONNECTION);
-  ndb->setDatabaseName(db);
 
   NDBDICT* dict= ndb->getDictionary();
-  dict->invalidateTable(name);
-  if (!(tab= dict->getTable(name)))
+  NdbDictionary::Dictionary::List list;
+  if (dict->listObjects(list, NdbDictionary::Object::UserTable) != 0)
+    ERR_RETURN(dict->getNdbError());
+  for (int i= 0 ; i < list.count ; i++)
   {
-    const NdbError err= dict->getNdbError();
-    if (err.code == 709 || err.code == 723)
-      DBUG_RETURN(0);
-    ERR_RETURN(err);
+    NdbDictionary::Dictionary::List::Element& elmt= list.elements[i];
+    if (my_strcasecmp(system_charset_info, elmt.database, db))
+      continue;
+    if (my_strcasecmp(system_charset_info, elmt.name, name))
+      continue;
+    // table found
+    DBUG_PRINT("info", ("Found table"));
+    DBUG_RETURN(1);
   }
-
-  DBUG_PRINT("info", ("Found table %s", tab->getName()));
-  DBUG_RETURN(1);
+  DBUG_RETURN(0);
 }
 
 
@@ -5902,9 +5794,9 @@ int ndbcluster_find_all_files(THD *thd)
       }
 
       ndb->setDatabaseName(elmt.database);
-      const NDBTAB *ndbtab;
-
-      if (!(ndbtab= dict->getTable(elmt.name)))
+      Ndb_table_guard ndbtab_g(dict, elmt.name);
+      const NDBTAB *ndbtab= ndbtab_g.get_table();
+      if (!ndbtab)
       {
         if (retries == 0)
           sql_print_error("NDB: failed to setup table %s.%s, error: %d, %s",
@@ -6184,11 +6076,13 @@ static int connect_callback()
   return 0;
 }
 
+extern int ndb_dictionary_is_mysqld;
 static bool ndbcluster_init()
 {
   int res;
   DBUG_ENTER("ndbcluster_init");
 
+  ndb_dictionary_is_mysqld= 1;
   if (have_ndbcluster != SHOW_OPTION_YES)
     goto ndbcluster_init_error;
 
@@ -6320,6 +6214,24 @@ static int ndbcluster_end(ha_panic_function type)
   if (!ndbcluster_inited)
     DBUG_RETURN(0);
 
+#ifdef HAVE_NDB_BINLOG
+  {
+    pthread_mutex_lock(&ndbcluster_mutex);
+    while (ndbcluster_open_tables.records)
+    {
+      NDB_SHARE *share=
+        (NDB_SHARE*) hash_element(&ndbcluster_open_tables, 0);
+#ifndef DBUG_OFF
+      fprintf(stderr, "NDB: table share %s with use_count %d not freed\n",
+              share->key, share->use_count);
+#endif
+      real_free_share(&share);
+    }
+    pthread_mutex_unlock(&ndbcluster_mutex);
+  }
+#endif
+  hash_free(&ndbcluster_open_tables);
+
   if (g_ndb)
   {
 #ifndef DBUG_OFF
@@ -6341,23 +6253,6 @@ static int ndbcluster_end(ha_panic_function type)
   delete g_ndb_cluster_connection;
   g_ndb_cluster_connection= NULL;
 
-#ifdef HAVE_NDB_BINLOG
-  {
-    pthread_mutex_lock(&ndbcluster_mutex);
-    for (uint i= 0; i < ndbcluster_open_tables.records; i++)
-    {
-      NDB_SHARE *share=
-        (NDB_SHARE*) hash_element(&ndbcluster_open_tables, i);
-#ifndef DBUG_OFF
-      fprintf(stderr, "NDB: table share %s with use_count %d not freed\n",
-              share->key, share->use_count);
-#endif
-      real_free_share(&share);
-    }
-    pthread_mutex_unlock(&ndbcluster_mutex);
-  }
-#endif
-  hash_free(&ndbcluster_open_tables);
   pthread_mutex_destroy(&ndbcluster_mutex);
   pthread_mutex_destroy(&LOCK_ndb_util_thread);
   pthread_cond_destroy(&COND_ndb_util_thread);
@@ -6518,7 +6413,7 @@ ha_ndbcluster::records_in_range(uint inx, key_range *min_key,
     m_index[inx].index_stat != NULL)
   {
     NDB_INDEX_DATA& d=m_index[inx];
-    NDBINDEX* index=(NDBINDEX*)d.index;
+    const NDBINDEX* index= d.index;
     Ndb* ndb=get_ndb();
     NdbTransaction* trans=NULL;
     NdbIndexScanOperation* op=NULL;
@@ -6538,7 +6433,7 @@ ha_ndbcluster::records_in_range(uint inx, key_range *min_key,
       else
       {
         Ndb_statistics stat;
-        if ((res=ndb_get_table_statistics(ndb, m_tabname, &stat)) != 0)
+        if ((res=ndb_get_table_statistics(ndb, m_table, &stat)) != 0)
           break;
         table_rows=stat.row_count;
         DBUG_PRINT("info", ("use db row_count: %llu", table_rows));
@@ -6699,10 +6594,14 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
   pthread_mutex_unlock(&share->mutex);
 
   struct Ndb_statistics stat;
-  if (ndb_get_table_statistics(ndb, tabname, &stat))
   {
-    free_share(&share);
-    DBUG_RETURN(1);
+    Ndb_table_guard ndbtab_g(ndb->getDictionary(), tabname);
+    if (ndbtab_g.get_table() == 0
+        || ndb_get_table_statistics(ndb, ndbtab_g.get_table(), &stat))
+    {
+      free_share(&share);
+      DBUG_RETURN(1);
+    }
   }
 
   pthread_mutex_lock(&share->mutex);
@@ -6916,7 +6815,11 @@ int handle_trailing_share(NDB_SHARE *share)
   ++share->use_count;
   pthread_mutex_unlock(&ndbcluster_mutex);
 
-  close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, TRUE);
+  TABLE_LIST table_list;
+  bzero((char*) &table_list,sizeof(table_list));
+  table_list.db= share->db;
+  table_list.alias= table_list.table_name= share->table_name;
+  close_cached_tables(current_thd, 0, &table_list, TRUE);
 
   pthread_mutex_lock(&ndbcluster_mutex);
   if (!--share->use_count)
@@ -7262,17 +7165,32 @@ void ndbcluster_free_share(NDB_SHARE **share, bool have_lock)
 
 static 
 int
-ndb_get_table_statistics(Ndb* ndb, const char * table,
+ndb_get_table_statistics(Ndb* ndb, const NDBTAB *ndbtab,
                          struct Ndb_statistics * ndbstat)
 {
   DBUG_ENTER("ndb_get_table_statistics");
-  DBUG_PRINT("enter", ("table: %s", table));
-  NdbTransaction* pTrans= ndb->startTransaction();
-  if (pTrans == NULL)
-    ERR_RETURN(ndb->getNdbError());
-  do 
+  DBUG_PRINT("enter", ("table: %s", ndbtab->getName()));
+  NdbTransaction* pTrans;
+  int retries= 10;
+  int retry_sleep= 30 * 1000; /* 30 milliseconds */
+
+  DBUG_ASSERT(ndbtab != 0);
+
+  do
   {
-    NdbScanOperation* pOp= pTrans->getNdbScanOperation(table);
+    pTrans= ndb->startTransaction();
+    if (pTrans == NULL)
+    {
+      if (ndb->getNdbError().status == NdbError::TemporaryError &&
+          retries--)
+      {
+        my_sleep(retry_sleep);
+        continue;
+      }
+      ERR_RETURN(ndb->getNdbError());
+    }
+
+    NdbScanOperation* pOp= pTrans->getNdbScanOperation(ndbtab);
     if (pOp == NULL)
       break;
     
@@ -7294,8 +7212,18 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
                            NdbTransaction::AbortOnError,
                            TRUE);
     if (check == -1)
+    {
+      if (pTrans->getNdbError().status == NdbError::TemporaryError &&
+          retries--)
+      {
+        ndb->closeTransaction(pTrans);
+        pTrans= 0;
+        my_sleep(retry_sleep);
+        continue;
+      }
       break;
-    
+    }
+
     Uint32 count= 0;
     Uint64 sum_rows= 0;
     Uint64 sum_commits= 0;
@@ -7329,7 +7257,7 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
                         sum_mem, count));
 
     DBUG_RETURN(0);
-  } while (0);
+  } while(1);
 
   if (pTrans)
     ndb->closeTransaction(pTrans);
@@ -7423,9 +7351,9 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
   byte *end_of_buffer= (byte*)buffer->buffer_end;
   NdbOperation::LockMode lm= 
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
-  const NDBTAB *tab= (const NDBTAB *) m_table;
-  const NDBINDEX *unique_idx= (NDBINDEX *) m_index[active_index].unique_index;
-  const NDBINDEX *idx= (NDBINDEX *) m_index[active_index].index; 
+  const NDBTAB *tab= m_table;
+  const NDBINDEX *unique_idx= m_index[active_index].unique_index;
+  const NDBINDEX *idx= m_index[active_index].index; 
   const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation();
   NdbIndexScanOperation* scanOp= 0;
   for (; multi_range_currsetDatabaseName(m_dbname);
   NDBDICT* dict= ndb->getDictionary();
-  const NDBTAB* tab;
-  if (!(tab= dict->getTable(m_tabname)))
-  {
-    return((char*)comment);
-  }
+  const NDBTAB* tab= m_table;
+  DBUG_ASSERT(tab != NULL);
 
   char *str;
   const char *fmt="%s%snumber_of_replicas: %d";
@@ -7964,18 +7889,22 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
       lock= share->commit_count_lock;
       pthread_mutex_unlock(&share->mutex);
 
-      if (ndb_get_table_statistics(ndb, share->table_name, &stat) == 0)
       {
-        DBUG_PRINT("ndb_util_thread",
-                   ("Table: %s, commit_count: %llu, rows: %llu",
-                    share->key, stat.commit_count, stat.row_count));
-      }
-      else
-      {
-        DBUG_PRINT("ndb_util_thread",
-                   ("Error: Could not get commit count for table %s",
-                    share->key));
-        stat.commit_count= 0;
+        Ndb_table_guard ndbtab_g(ndb->getDictionary(), share->table_name);
+        if (ndbtab_g.get_table() &&
+            ndb_get_table_statistics(ndb, ndbtab_g.get_table(), &stat) == 0)
+        {
+          DBUG_PRINT("ndb_util_thread",
+                     ("Table: %s, commit_count: %llu, rows: %llu",
+                      share->key, stat.commit_count, stat.row_count));
+        }
+        else
+        {
+          DBUG_PRINT("ndb_util_thread",
+                     ("Error: Could not get commit count for table %s",
+                      share->key));
+          stat.commit_count= 0;
+        }
       }
 
       pthread_mutex_lock(&share->mutex);
@@ -9367,12 +9296,8 @@ char* ha_ndbcluster::get_tablespace_name(THD *thd)
   NdbError ndberr;
   Uint32 id;
   ndb->setDatabaseName(m_dbname);
-  const NDBTAB *ndbtab= ndbdict->getTable(m_tabname);
-  if (ndbtab == 0)
-  {
-    ndberr= ndbdict->getNdbError();
-    goto err;
-  }
+  const NDBTAB *ndbtab= m_table;
+  DBUG_ASSERT(ndbtab != NULL);
   if (!ndbtab->getTablespace(&id))
   {
     return 0;
@@ -10037,17 +9962,10 @@ bool ha_ndbcluster::get_no_parts(const char *name, uint *no_parts)
     }
     ndb= get_ndb();
     ndb->setDatabaseName(m_dbname);
-    dict= ndb->getDictionary();
-    if (!(tab= dict->getTable(m_tabname)))
+    Ndb_table_guard ndbtab_g(dict= ndb->getDictionary(), m_tabname);
+    if (!ndbtab_g.get_table())
       ERR_BREAK(dict->getNdbError(), err);
-    // Check if thread has stale local cache
-    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
-    {
-      invalidate_dictionary_cache(FALSE, tab);
-      if (!(tab= dict->getTable(m_tabname)))
-         ERR_BREAK(dict->getNdbError(), err);
-    }
-    *no_parts= tab->getFragmentCount();
+    *no_parts= ndbtab_g.get_table()->getFragmentCount();
     DBUG_RETURN(FALSE);
   } while (1);
 
@@ -10255,3 +10173,20 @@ static int ndbcluster_fill_files_table(THD *thd, TABLE_LIST *tables, COND *cond)
   }
   DBUG_RETURN(0);
 }
+
+
+mysql_declare_plugin(ndbcluster)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &ndbcluster_hton,
+  ndbcluster_hton_name,
+  "MySQL AB",
+  ndbcluster_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+  0
+}
+mysql_declare_plugin_end;
+
+#endif
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 0af65a373bd..f407cb0090f 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -70,8 +70,8 @@ typedef enum ndb_index_status {
 typedef struct ndb_index_data {
   NDB_INDEX_TYPE type;
   NDB_INDEX_STATUS status;  
-  void *index;
-  void *unique_index;
+  const NdbDictionary::Index *index;
+  const NdbDictionary::Index *unique_index;
   unsigned char *unique_index_attrid_map;
   // In this version stats are not shared between threads
   NdbIndexStat* index_stat;
@@ -560,6 +560,7 @@ class ha_ndbcluster: public handler
   ha_ndbcluster(TABLE_SHARE *table);
   ~ha_ndbcluster();
 
+  int ha_initialise();
   int open(const char *name, int mode, uint test_if_locked);
   int close(void);
 
@@ -708,23 +709,17 @@ private:
                                       Ndb *ndb, NdbEventOperation *pOp,
                                       NDB_SHARE *share);
 
-  int alter_table_name(const char *to);
   static int delete_table(ha_ndbcluster *h, Ndb *ndb,
 			  const char *path,
 			  const char *db,
 			  const char *table_name);
-  int drop_ndb_table();
   int create_ndb_index(const char *name, KEY *key_info, bool unique);
   int create_ordered_index(const char *name, KEY *key_info);
   int create_unique_index(const char *name, KEY *key_info);
   int create_index(const char *name, KEY *key_info, 
                    NDB_INDEX_TYPE idx_type, uint idx_no);
-  int drop_ndb_index(const char *name);
-  int table_changed(const void *pack_frm_data, uint pack_frm_len);
 // Index list management
   int create_indexes(Ndb *ndb, TABLE *tab);
-  void clear_index(int i);
-  void clear_indexes();
   int open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error);
   void renumber_indexes(Ndb *ndb, TABLE *tab);
   int drop_indexes(Ndb *ndb, TABLE *tab);
@@ -732,7 +727,7 @@ private:
                        KEY *key_info, const char *index_name, uint index_no);
   int initialize_autoincrement(const void *table);
   int get_metadata(const char* path);
-  void release_metadata();
+  void release_metadata(THD *thd, Ndb *ndb);
   NDB_INDEX_TYPE get_index_type(uint idx_no) const;
   NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
   NDB_INDEX_TYPE get_index_type_from_key(uint index_no, KEY *key_info, 
@@ -795,8 +790,6 @@ private:
   void print_results();
 
   ulonglong get_auto_increment();
-  int invalidate_dictionary_cache(bool global,
-                                  const NdbDictionary::Table *ndbtab);
   int ndb_err(NdbTransaction*);
   bool uses_blob_value();
 
@@ -834,7 +827,6 @@ private:
   NdbTransaction *m_active_trans;
   NdbScanOperation *m_active_cursor;
   const NdbDictionary::Table *m_table;
-  int m_table_version;
   struct Ndb_local_table_statistics *m_table_info;
   char m_dbname[FN_HEADLEN];
   //char m_schemaname[FN_HEADLEN];
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index a39d92ae7a5..6139234a50e 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -16,6 +16,7 @@
 */
 
 #include "mysql_priv.h"
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 #include "ha_ndbcluster.h"
 
 #ifdef HAVE_NDB_BINLOG
@@ -986,7 +987,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
                              uint32 ndb_table_id,
                              uint32 ndb_table_version,
                              enum SCHEMA_OP_TYPE type,
-                             const char *old_db, const char *old_table_name)
+                             const char *new_db, const char *new_table_name)
 {
   DBUG_ENTER("ndbcluster_log_schema_op");
   Thd_ndb *thd_ndb= get_thd_ndb(thd);
@@ -1026,8 +1027,8 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
     /* redo the rename table query as is may contain several tables */
     query= tmp_buf2;
     query_length= (uint) (strxmov(tmp_buf2, "rename table `",
-                                  old_db, ".", old_table_name, "` to `",
-                                  db, ".", table_name, "`", NullS) - tmp_buf2);
+                                  db, ".", table_name, "` to `",
+                                  new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
     type_str= "rename table";
     break;
   case SOT_CREATE_TABLE:
@@ -1067,6 +1068,8 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
   Uint64 epoch= 0;
   MY_BITMAP schema_subscribers;
   uint32 bitbuf[sizeof(ndb_schema_object->slock)/4];
+  uint32 bitbuf_e[sizeof(bitbuf)];
+  bzero((char *)bitbuf_e, sizeof(bitbuf_e));
   {
     int i, updated= 0;
     int no_storage_nodes= g_ndb_cluster_connection->no_db_nodes();
@@ -1110,7 +1113,8 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
   char tmp_buf[FN_REFLEN];
   NDBDICT *dict= ndb->getDictionary();
   ndb->setDatabaseName(NDB_REP_DB);
-  const NDBTAB *ndbtab= dict->getTable(NDB_SCHEMA_TABLE);
+  Ndb_table_guard ndbtab_g(dict, NDB_SCHEMA_TABLE);
+  const NDBTAB *ndbtab= ndbtab_g.get_table();
   NdbTransaction *trans= 0;
   int retries= 100;
   const NDBCOL *col[SCHEMA_SIZE];
@@ -1141,8 +1145,13 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
 
   while (1)
   {
+    const char *log_db= db;
+    const char *log_tab= table_name;
+    const char *log_subscribers= (char*)schema_subscribers.bitmap;
+    uint32 log_type= (uint32)type;
     if ((trans= ndb->startTransaction()) == 0)
       goto err;
+    while (1)
     {
       NdbOperation *op= 0;
       int r= 0;
@@ -1152,17 +1161,17 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
       DBUG_ASSERT(r == 0);
       
       /* db */
-      ndb_pack_varchar(col[SCHEMA_DB_I], tmp_buf, db, strlen(db));
+      ndb_pack_varchar(col[SCHEMA_DB_I], tmp_buf, log_db, strlen(log_db));
       r|= op->equal(SCHEMA_DB_I, tmp_buf);
       DBUG_ASSERT(r == 0);
       /* name */
-      ndb_pack_varchar(col[SCHEMA_NAME_I], tmp_buf, table_name,
-                       strlen(table_name));
+      ndb_pack_varchar(col[SCHEMA_NAME_I], tmp_buf, log_tab,
+                       strlen(log_tab));
       r|= op->equal(SCHEMA_NAME_I, tmp_buf);
       DBUG_ASSERT(r == 0);
       /* slock */
       DBUG_ASSERT(sz[SCHEMA_SLOCK_I] == sizeof(bitbuf));
-      r|= op->setValue(SCHEMA_SLOCK_I, (char*)schema_subscribers.bitmap);
+      r|= op->setValue(SCHEMA_SLOCK_I, log_subscribers);
       DBUG_ASSERT(r == 0);
       /* query */
       {
@@ -1186,8 +1195,17 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
       r|= op->setValue(SCHEMA_VERSION_I, ndb_table_version);
       DBUG_ASSERT(r == 0);
       /* type */
-      r|= op->setValue(SCHEMA_TYPE_I, (uint32)type);
+      r|= op->setValue(SCHEMA_TYPE_I, log_type);
       DBUG_ASSERT(r == 0);
+      if (log_db != new_db && new_db && new_table_name)
+      {
+        log_db= new_db;
+        log_tab= new_table_name;
+        log_subscribers= (const char *)bitbuf_e; // no ack expected on this
+        log_type= (uint32)SOT_RENAME_TABLE_NEW;
+        continue;
+      }
+      break;
     }
     if (trans->execute(NdbTransaction::Commit) == 0)
     {
@@ -1306,7 +1324,8 @@ ndbcluster_update_slock(THD *thd,
   char tmp_buf[FN_REFLEN];
   NDBDICT *dict= ndb->getDictionary();
   ndb->setDatabaseName(NDB_REP_DB);
-  const NDBTAB *ndbtab= dict->getTable(NDB_SCHEMA_TABLE);
+  Ndb_table_guard ndbtab_g(dict, NDB_SCHEMA_TABLE);
+  const NDBTAB *ndbtab= ndbtab_g.get_table();
   NdbTransaction *trans= 0;
   int retries= 100;
   const NDBCOL *col[SCHEMA_SIZE];
@@ -1452,31 +1471,28 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
   {
     if (pOp->tableFrmChanged())
     {
+      DBUG_PRINT("info", ("NDBEVENT::TE_ALTER: table frm changed"));
       is_online_alter_table= TRUE;
     }
     else
     {
+      DBUG_PRINT("info", ("NDBEVENT::TE_ALTER: name changed"));
       DBUG_ASSERT(pOp->tableNameChanged());
       is_rename_table= TRUE;
     }
   }
 
-  /*
-    Refresh local dictionary cache by
-    invalidating table and all it's indexes
-  */
-  ndb->setDatabaseName(dbname);
-  Thd_ndb *thd_ndb= get_thd_ndb(thd);
-  DBUG_ASSERT(thd_ndb != NULL);
-  Ndb* old_ndb= thd_ndb->ndb;
-  thd_ndb->ndb= ndb;
-  ha_ndbcluster table_handler(table_share);
-  (void)strxmov(table_handler.m_dbname, dbname, NullS);
-  (void)strxmov(table_handler.m_tabname, tabname, NullS);
-  table_handler.open_indexes(ndb, table, TRUE);
-  table_handler.invalidate_dictionary_cache(TRUE, 0);
-  thd_ndb->ndb= old_ndb;
-  
+  {
+    ndb->setDatabaseName(dbname);
+    Ndb_table_guard ndbtab_g(ndb->getDictionary(), tabname);
+    const NDBTAB *ev_tab= pOp->getTable();
+    const NDBTAB *cache_tab= ndbtab_g.get_table();
+    if (cache_tab &&
+        cache_tab->getObjectId() == ev_tab->getObjectId() &&
+        cache_tab->getObjectVersion() <= ev_tab->getObjectVersion())
+      ndbtab_g.invalidate();
+  }
+
   /*
     Refresh local frm file and dictionary cache if
     remote on-line alter table
@@ -1505,7 +1521,8 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
       DBUG_DUMP("frm", (char*)altered_table->getFrmData(), 
                 altered_table->getFrmLength());
       pthread_mutex_lock(&LOCK_open);
-      const NDBTAB *old= dict->getTable(tabname);
+      Ndb_table_guard ndbtab_g(dict, tabname);
+      const NDBTAB *old= ndbtab_g.get_table();
       if (!old &&
           old->getObjectVersion() != altered_table->getObjectVersion())
         dict->putTable(altered_table);
@@ -1517,7 +1534,13 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
                               dbname, tabname, error);
       }
       ndbcluster_binlog_close_table(thd, share);
-      close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, TRUE);
+
+      TABLE_LIST table_list;
+      bzero((char*) &table_list,sizeof(table_list));
+      table_list.db= (char *)dbname;
+      table_list.alias= table_list.table_name= (char *)tabname;
+      close_cached_tables(thd, 0, &table_list, TRUE);
+
       if ((error= ndbcluster_binlog_open_table(thd, share, 
                                                table_share, table)))
         sql_print_information("NDB: Failed to re-open table %s.%s",
@@ -1545,26 +1568,22 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
                             share_prefix, share->table->s->db.str,
                             share->table->s->table_name.str,
                             share->key);
+    {
+      ndb->setDatabaseName(share->table->s->db.str);
+      Ndb_table_guard ndbtab_g(ndb->getDictionary(),
+                               share->table->s->table_name.str);
+      const NDBTAB *ev_tab= pOp->getTable();
+      const NDBTAB *cache_tab= ndbtab_g.get_table();
+      if (cache_tab &&
+          cache_tab->getObjectId() == ev_tab->getObjectId() &&
+          cache_tab->getObjectVersion() <= ev_tab->getObjectVersion())
+        ndbtab_g.invalidate();
+    }
     /* do the rename of the table in the share */
     share->table->s->db.str= share->db;
     share->table->s->db.length= strlen(share->db);
     share->table->s->table_name.str= share->table_name;
     share->table->s->table_name.length= strlen(share->table_name);
-    /*
-      Refresh local dictionary cache by invalidating any 
-      old table with same name and all it's indexes
-    */
-    ndb->setDatabaseName(dbname);
-    Thd_ndb *thd_ndb= get_thd_ndb(thd);
-    DBUG_ASSERT(thd_ndb != NULL);
-    Ndb* old_ndb= thd_ndb->ndb;
-    thd_ndb->ndb= ndb;
-    ha_ndbcluster table_handler(table_share);
-    table_handler.set_dbname(share->key);
-    table_handler.set_tabname(share->key);
-    table_handler.open_indexes(ndb, table, TRUE);
-    table_handler.invalidate_dictionary_cache(TRUE, 0);
-    thd_ndb->ndb= old_ndb;
   }
   DBUG_ASSERT(share->op == pOp || share->op_old == pOp);
   if (share->op_old == pOp)
@@ -1582,14 +1601,19 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
   if (is_remote_change && share && share->state != NSS_DROPPED)
   {
     DBUG_PRINT("info", ("remote change"));
+    share->state= NSS_DROPPED;
     if (share->use_count != 1)
       do_close_cached_tables= TRUE;
-    share->state= NSS_DROPPED;
-    free_share(&share, TRUE);
+    else
+    {
+      free_share(&share, TRUE);
+      share= 0;
+    }
   }
+  else
+    share= 0;
   pthread_mutex_unlock(&ndbcluster_mutex);
 
-  share= 0;
   pOp->setCustomData(0);
 
   pthread_mutex_lock(&injector_mutex);
@@ -1598,7 +1622,14 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
   pthread_mutex_unlock(&injector_mutex);
 
   if (do_close_cached_tables)
-    close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0);
+  {
+    TABLE_LIST table_list;
+    bzero((char*) &table_list,sizeof(table_list));
+    table_list.db= (char *)dbname;
+    table_list.alias= table_list.table_name= (char *)tabname;
+    close_cached_tables(thd, 0, &table_list);
+    free_share(&share);
+  }
   DBUG_RETURN(0);
 }
 
@@ -1630,53 +1661,27 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
       if (schema->node_id != node_id)
       {
         int log_query= 0, post_epoch_unlock= 0;
-        DBUG_PRINT("info", ("log query_length: %d  query: '%s'",
-                            schema->query_length, schema->query));
+        DBUG_PRINT("info",
+                   ("%s.%s: log query_length: %d  query: '%s'  type: %d",
+                    schema->db, schema->name,
+                    schema->query_length, schema->query,
+                    schema->type));
         char key[FN_REFLEN];
         build_table_filename(key, sizeof(key), schema->db, schema->name, "");
-        NDB_SHARE *share= get_share(key, 0, false, false);
         switch ((enum SCHEMA_OP_TYPE)schema->type)
         {
         case SOT_DROP_TABLE:
-          /* binlog dropping table after any table operations */
-          if (share && share->op)
-          {
-            post_epoch_log_list->push_back(schema, mem_root);
-            /* acknowledge this query _after_ epoch completion */
-            post_epoch_unlock= 1;
-          }
-          /* table is either ignored or logging is postponed to later */
-          log_query= 0;
-          break;
+          // fall through
         case SOT_RENAME_TABLE:
-          if (share && share->op)
-          {
-            post_epoch_log_list->push_back(schema, mem_root);
-            /* acknowledge this query _after_ epoch completion */
-            post_epoch_unlock= 1;
-            break; /* discovery will be handled by binlog */
-          }
-          goto sot_create_table;
+          // fall through
+        case SOT_RENAME_TABLE_NEW:
+          // fall through
         case SOT_ALTER_TABLE:
-          if (share && share->op)
-          {
-            post_epoch_log_list->push_back(schema, mem_root);
-            /* acknowledge this query _after_ epoch completion */
-            post_epoch_unlock= 1;
-            break; /* discovery will be handled by binlog */
-          }
-          goto sot_create_table;
+          post_epoch_log_list->push_back(schema, mem_root);
+          /* acknowledge this query _after_ epoch completion */
+          post_epoch_unlock= 1;
+          break;
         case SOT_CREATE_TABLE:
-      sot_create_table:
-          /*
-            we need to free any share here as command below
-            may need to call handle_trailing_share
-          */
-          if (share)
-          {
-            free_share(&share);
-            share= 0;
-          }
           pthread_mutex_lock(&LOCK_open);
           if (ndb_create_table_from_engine(thd, schema->db, schema->name))
           {
@@ -1694,12 +1699,9 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
                     TRUE,    /* print error */
                     TRUE);   /* don't binlog the query */
           /* binlog dropping database after any table operations */
-          if (ndb_binlog_running)
-          {
-            post_epoch_log_list->push_back(schema, mem_root);
-            /* acknowledge this query _after_ epoch completion */
-            post_epoch_unlock= 1;
-          }
+          post_epoch_log_list->push_back(schema, mem_root);
+          /* acknowledge this query _after_ epoch completion */
+          post_epoch_unlock= 1;
           break;
         case SOT_CREATE_DB:
           /* fall through */
@@ -1726,8 +1728,6 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
             pthread_mutex_unlock(&ndb_schema_object->mutex);
             pthread_cond_signal(&injector_cond);
           }
-          if (share)
-            free_share(&share, TRUE);
           pthread_mutex_unlock(&ndbcluster_mutex);
           DBUG_RETURN(0);
         }
@@ -1736,11 +1736,6 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
           log_query= 1;
           break;
         }
-        if (share)
-        {
-          free_share(&share);
-          share= 0;
-        }
         if (log_query && ndb_binlog_running)
         {
           char *thd_db_save= thd->db;
@@ -1864,36 +1859,81 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
                                                  List
                                                  *post_epoch_unlock_list)
 {
+  if (post_epoch_log_list->elements == 0)
+    return;
   DBUG_ENTER("ndb_binlog_thread_handle_schema_event_post_epoch");
   Cluster_schema *schema;
   while ((schema= post_epoch_log_list->pop()))
   {
-    DBUG_PRINT("info", ("log query_length: %d  query: '%s'",
-                        schema->query_length, schema->query));
+    DBUG_PRINT("info",
+               ("%s.%s: log query_length: %d  query: '%s'  type: %d",
+                schema->db, schema->name,
+                schema->query_length, schema->query,
+                schema->type));
+    int log_query= 0;
     {
       char key[FN_REFLEN];
       build_table_filename(key, sizeof(key), schema->db, schema->name, "");
       NDB_SHARE *share= get_share(key, 0, false, false);
-      switch ((enum SCHEMA_OP_TYPE)schema->type)
+      enum SCHEMA_OP_TYPE schema_type= (enum SCHEMA_OP_TYPE)schema->type;
+      switch (schema_type)
       {
       case SOT_DROP_DB:
-      case SOT_DROP_TABLE:
+        log_query= 1;
         break;
-      case SOT_RENAME_TABLE:
-      case SOT_ALTER_TABLE:
+      case SOT_DROP_TABLE:
+        // invalidation already handled by binlog thread
         if (share && share->op)
         {
-          break; /* discovery handled by binlog */
+          log_query= 1;
+          break;
         }
-        pthread_mutex_lock(&LOCK_open);
-        if (ndb_create_table_from_engine(thd, schema->db, schema->name))
+        // fall through
+      case SOT_RENAME_TABLE:
+        // fall through
+      case SOT_ALTER_TABLE:
+        // invalidation already handled by binlog thread
+        if (!share || !share->op)
         {
-          sql_print_error("Could not discover table '%s.%s' from "
-                          "binlog schema event '%s' from node %d",
-                          schema->db, schema->name, schema->query,
-                          schema->node_id);
+          {
+            injector_ndb->setDatabaseName(schema->db);
+            Ndb_table_guard ndbtab_g(injector_ndb->getDictionary(),
+                                     schema->name);
+            ndbtab_g.invalidate();
+          }
+          TABLE_LIST table_list;
+          bzero((char*) &table_list,sizeof(table_list));
+          table_list.db= schema->db;
+          table_list.alias= table_list.table_name= schema->name;
+          close_cached_tables(thd, 0, &table_list, FALSE);
         }
-        pthread_mutex_unlock(&LOCK_open);
+        if (schema_type != SOT_ALTER_TABLE)
+          break;
+        // fall through
+      case SOT_RENAME_TABLE_NEW:
+        log_query= 1;
+        if (ndb_binlog_running)
+        {
+          /*
+            we need to free any share here as command below
+            may need to call handle_trailing_share
+          */
+          if (share)
+          {
+            free_share(&share);
+            share= 0;
+          }
+          pthread_mutex_lock(&LOCK_open);
+          if (ndb_create_table_from_engine(thd, schema->db, schema->name))
+          {
+            sql_print_error("Could not discover table '%s.%s' from "
+                            "binlog schema event '%s' from node %d",
+                            schema->db, schema->name, schema->query,
+                            schema->node_id);
+          }
+          pthread_mutex_unlock(&LOCK_open);
+        }
+        break;
       default:
         DBUG_ASSERT(false);
       }
@@ -1903,6 +1943,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd,
         share= 0;
       }
     }
+    if (ndb_binlog_running && log_query)
     {
       char *thd_db_save= thd->db;
       thd->db= schema->db;
@@ -2186,7 +2227,8 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
     ndb->setDatabaseName(db);
 
     NDBDICT *dict= ndb->getDictionary();
-    const NDBTAB *ndbtab= dict->getTable(table_name);
+    Ndb_table_guard ndbtab_g(dict, table_name);
+    const NDBTAB *ndbtab= ndbtab_g.get_table();
     if (ndbtab == 0)
     {
       if (ndb_extra_logging)
@@ -2201,7 +2243,8 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
       event should have been created by someone else,
       but let's make sure, and create if it doesn't exist
     */
-    if (!dict->getEvent(event_name.c_ptr()))
+    const NDBEVENT *ev= dict->getEvent(event_name.c_ptr());
+    if (!ev)
     {
       if (ndbcluster_create_event(ndb, ndbtab, event_name.c_ptr(), share))
       {
@@ -2216,9 +2259,12 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
                               event_name.c_ptr());
     }
     else
+    {
+      delete ev;
       if (ndb_extra_logging)
         sql_print_information("NDB Binlog: DISCOVER TABLE Event: %s",
                               event_name.c_ptr());
+    }
 
     /*
       create the event operations for receiving logging events
@@ -2328,8 +2374,10 @@ ndbcluster_create_event(Ndb *ndb, const NDBTAB *ndbtab,
       try retrieving the event, if table version/id matches, we will get
       a valid event.  Otherwise we have a trailing event from before
     */
-    if (dict->getEvent(event_name))
+    const NDBEVENT *ev;
+    if ((ev= dict->getEvent(event_name)))
     {
+      delete ev;
       DBUG_RETURN(0);
     }
 
@@ -3648,3 +3696,4 @@ ndbcluster_show_status_binlog(THD* thd, stat_print_fn *stat_print,
 }
 
 #endif /* HAVE_NDB_BINLOG */
+#endif
diff --git a/sql/ha_ndbcluster_binlog.h b/sql/ha_ndbcluster_binlog.h
index 9d15016568b..d82cdccb1b9 100644
--- a/sql/ha_ndbcluster_binlog.h
+++ b/sql/ha_ndbcluster_binlog.h
@@ -41,14 +41,15 @@ enum SCHEMA_OP_TYPE
 {
   SOT_DROP_TABLE= 0,
   SOT_CREATE_TABLE= 1,
-  SOT_RENAME_TABLE= 2,
+  SOT_RENAME_TABLE_NEW= 2,
   SOT_ALTER_TABLE= 3,
   SOT_DROP_DB= 4,
   SOT_CREATE_DB= 5,
   SOT_ALTER_DB= 6,
   SOT_CLEAR_SLOCK= 7,
   SOT_TABLESPACE= 8,
-  SOT_LOGFILE_GROUP= 9
+  SOT_LOGFILE_GROUP= 9,
+  SOT_RENAME_TABLE= 10
 };
 
 const uint max_ndb_nodes= 64; /* multiple of 32 */
@@ -56,6 +57,45 @@ const uint max_ndb_nodes= 64; /* multiple of 32 */
 static const char *ha_ndb_ext=".ndb";
 static const char share_prefix[]= "./";
 
+class Ndb_table_guard
+{
+public:
+  Ndb_table_guard(NDBDICT *dict, const char *tabname)
+    : m_dict(dict)
+  {
+    DBUG_ENTER("Ndb_table_guard");
+    m_ndbtab= m_dict->getTableGlobal(tabname);
+    m_invalidate= 0;
+    DBUG_PRINT("info", ("m_ndbtab: %p", m_ndbtab));
+    DBUG_VOID_RETURN;
+  }
+  ~Ndb_table_guard()
+  {
+    DBUG_ENTER("~Ndb_table_guard");
+    if (m_ndbtab)
+    {
+      DBUG_PRINT("info", ("m_ndbtab: %p  m_invalidate: %d",
+                          m_ndbtab, m_invalidate));
+      m_dict->removeTableGlobal(*m_ndbtab, m_invalidate);
+    }
+    DBUG_VOID_RETURN;
+  }
+  const NDBTAB *get_table() { return m_ndbtab; }
+  void invalidate() { m_invalidate= 1; }
+  const NDBTAB *release()
+  {
+    DBUG_ENTER("Ndb_table_guard::release");
+    const NDBTAB *tmp= m_ndbtab;
+    DBUG_PRINT("info", ("m_ndbtab: %p", m_ndbtab));
+    m_ndbtab = 0;
+    DBUG_RETURN(tmp);
+  }
+private:
+  const NDBTAB *m_ndbtab;
+  NDBDICT *m_dict;
+  int m_invalidate;
+};
+
 #ifdef HAVE_NDB_BINLOG
 extern pthread_t ndb_binlog_thread;
 extern pthread_mutex_t injector_mutex;
@@ -98,8 +138,8 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
                              uint32 ndb_table_id,
                              uint32 ndb_table_version,
                              enum SCHEMA_OP_TYPE type,
-                             const char *old_db= 0,
-                             const char *old_table_name= 0);
+                             const char *new_db= 0,
+                             const char *new_table_name= 0);
 int ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name,
                                  NDB_SHARE *share,
                                  const char *type_str);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 1ab2c4270fd..b1a5a447b6f 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -54,8 +54,11 @@
 
 #include "mysql_priv.h"
 
+#ifdef WITH_PARTITION_STORAGE_ENGINE
 #include "ha_partition.h"
 
+#include 
+
 static const char *ha_par_ext= ".par";
 #ifdef NOT_USED
 static int free_share(PARTITION_SHARE * share);
@@ -70,11 +73,14 @@ static handler *partition_create_handler(TABLE_SHARE *share);
 static uint partition_flags();
 static uint alter_table_flags(uint flags);
 
+static const char partition_hton_name[]= "partition";
+static const char partition_hton_comment[]= "Partition Storage Engine Helper";
+
 handlerton partition_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "partition",
+  partition_hton_name,
   SHOW_OPTION_YES,
-  "Partition Storage Engine Helper", /* A comment used by SHOW to describe an engine */
+  partition_hton_comment, /* A comment used by SHOW to describe an engine */
   DB_TYPE_PARTITION_DB,
   0, /* Method that initializes a storage engine */
   0, /* slot */
@@ -5438,3 +5444,20 @@ static int free_share(PARTITION_SHARE *share)
   return 0;
 }
 #endif /* NOT_USED */
+
+
+mysql_declare_plugin(partition)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &partition_hton,
+  partition_hton_name,
+  "Mikael Ronstrom, MySQL AB",
+  partition_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100, /* 1.0 */
+  0
+}
+mysql_declare_plugin_end;
+
+#endif
diff --git a/sql/handler.cc b/sql/handler.cc
index 808dd0841c5..b9ef05a33c2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -35,6 +35,7 @@
 #define NDB_MAX_ATTRIBUTES_IN_TABLE 128
 #include "ha_ndbcluster.h"
 #endif
+
 #ifdef WITH_PARTITION_STORAGE_ENGINE
 #include "ha_partition.h"
 #endif
@@ -43,10 +44,15 @@
 #include "ha_innodb.h"
 #endif
 
-extern handlerton *sys_table_types[];
+/* While we have legacy_db_type, we have this array to
+   check for dups and to find handlerton from legacy_db_type.
+   Remove when legacy_db_type is finally gone */
+static handlerton *installed_htons[128];
 
 #define BITMAP_STACKBUF_SIZE (128/8)
 
+KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NullS,0} };
+
 /* static functions defined in this file */
 
 static handler *create_default(TABLE_SHARE *table);
@@ -138,30 +144,8 @@ handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name)
 }
 
 
-struct plugin_find_dbtype_st
-{
-  enum legacy_db_type db_type;
-  handlerton *hton;
-};
-
-
-static my_bool plugin_find_dbtype(THD *unused, st_plugin_int *plugin,
-                                  void *arg)
-{
-  handlerton *types= (handlerton *) plugin->plugin->info;
-  if (types->db_type == ((struct plugin_find_dbtype_st *)arg)->db_type)
-  {
-    ((struct plugin_find_dbtype_st *)arg)->hton= types;
-    return TRUE;
-  }
-  return FALSE;
-}
-
-
 const char *ha_get_storage_engine(enum legacy_db_type db_type)
 {
-  struct plugin_find_dbtype_st info;
-  
   switch (db_type)
   {
   case DB_TYPE_DEFAULT:
@@ -169,13 +153,10 @@ const char *ha_get_storage_engine(enum legacy_db_type db_type)
   case DB_TYPE_UNKNOWN:
     return "UNKNOWN";
   default:
-    info.db_type= db_type;
-
-    if (!plugin_foreach(NULL, plugin_find_dbtype, 
-                        MYSQL_STORAGE_ENGINE_PLUGIN, &info))
+    if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
+        installed_htons[db_type])
+      return installed_htons[db_type]->name;
       return "*NONE*";
-
-    return info.hton->name;
   }
 }
 
@@ -190,8 +171,6 @@ static handler *create_default(TABLE_SHARE *table)
 
 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
 {
-  struct plugin_find_dbtype_st info;
-
   switch (db_type)
   {
   case DB_TYPE_DEFAULT:
@@ -202,12 +181,9 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
   case DB_TYPE_UNKNOWN:
     return NULL;
   default:
-    info.db_type= db_type;
-    if (!plugin_foreach(NULL, plugin_find_dbtype, 
-                        MYSQL_STORAGE_ENGINE_PLUGIN, &info))
+    if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT)
+      return installed_htons[db_type];
       return NULL;
-
-    return info.hton;
   }
 }
 
@@ -394,32 +370,77 @@ static int ha_finish_errors(void)
 }
 
 
-static void ha_was_inited_ok(handlerton *ht)
+int ha_finalize_handlerton(st_plugin_int *plugin)
 {
-  uint tmp= ht->savepoint_offset;
-  ht->savepoint_offset= savepoint_alloc_size;
-  savepoint_alloc_size+= tmp;
-  ht->slot= total_ha++;
-  if (ht->prepare)
-    total_ha_2pc++;
-}
+  handlerton *hton;
+  DBUG_ENTER("ha_finalize_handlerton");
 
-
-int ha_initialize_handlerton(handlerton *hton)
-{
-  DBUG_ENTER("ha_initialize_handlerton");
-
-  if (hton == NULL)
+  if (!(hton= (handlerton *) plugin->plugin->info))
     DBUG_RETURN(1);
 
   switch (hton->state)
   {
+  case SHOW_OPTION_NO:
+  case SHOW_OPTION_DISABLED:
+    break;
+  case SHOW_OPTION_YES:
+    if (hton->panic && hton->panic(HA_PANIC_CLOSE))
+      DBUG_RETURN(1);
+    if (installed_htons[hton->db_type] == hton)
+      installed_htons[hton->db_type]= NULL;
+    break;
+  };
+  DBUG_RETURN(0);
+}
+
+
+int ha_initialize_handlerton(st_plugin_int *plugin)
+{
+  handlerton *hton;
+  DBUG_ENTER("ha_initialize_handlerton");
+
+  if (!(hton= (handlerton *) plugin->plugin->info))
+    DBUG_RETURN(1);
+
+  /* for the sake of sanity, we set the handlerton name to be the
+     same as the plugin name */
+  hton->name= plugin->name.str;
+
+
+  switch (hton->state) {
   case SHOW_OPTION_NO:
     break;
   case SHOW_OPTION_YES:
     if (!hton->init || !hton->init())
     {
-      ha_was_inited_ok(hton);
+      uint tmp= hton->savepoint_offset;
+      hton->savepoint_offset= savepoint_alloc_size;
+      savepoint_alloc_size+= tmp;
+      hton->slot= total_ha++;
+      if (hton->prepare)
+        total_ha_2pc++;
+        
+      /* now check the db_type for conflict */
+      if (hton->db_type <= DB_TYPE_UNKNOWN || 
+          hton->db_type >= DB_TYPE_DEFAULT ||
+          installed_htons[hton->db_type])
+      {
+        int idx= (int) DB_TYPE_FIRST_DYNAMIC;
+        
+        while (idx < (int) DB_TYPE_DEFAULT && installed_htons[idx])
+          idx++;
+
+        if (idx == (int) DB_TYPE_DEFAULT)
+        {
+          sql_print_warning("Too many storage engines!");
+          DBUG_RETURN(1);
+        }
+        if (hton->db_type != DB_TYPE_UNKNOWN)
+          sql_print_warning("Storage engine '%s' has conflicting typecode. "
+                            "Assigning value %d.", hton->name, idx);
+        hton->db_type= (enum legacy_db_type) idx;
+      }
+      installed_htons[hton->db_type]= hton;
       break;
     }
     /* fall through */
@@ -436,7 +457,7 @@ static my_bool init_handlerton(THD *unused1, st_plugin_int *plugin,
 {
   if (plugin->state == PLUGIN_IS_UNINITIALIZED)
   {
-    ha_initialize_handlerton((handlerton *) plugin->plugin->info);
+    ha_initialize_handlerton(plugin);
     plugin->state= PLUGIN_IS_READY;
   }
   return FALSE;
@@ -447,12 +468,15 @@ int ha_init()
 {
   int error= 0;
   total_ha= savepoint_alloc_size= 0;
+  DBUG_ENTER("ha_init");
+
+  bzero(installed_htons, sizeof(installed_htons));
 
   if (ha_init_errors())
-    return 1;
+    DBUG_RETURN(1);
 
   if (plugin_foreach(NULL, init_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0))
-    return 1;
+    DBUG_RETURN(1);
 
   DBUG_ASSERT(total_ha < MAX_HA);
   /*
@@ -462,37 +486,7 @@ int ha_init()
   */
   opt_using_transactions= total_ha>(ulong)opt_bin_log;
   savepoint_alloc_size+= sizeof(SAVEPOINT);
-  return error;
-}
-
-
-int ha_register_builtin_plugins()
-{
-  handlerton **hton;
-  uint size= 0;
-  struct st_mysql_plugin *plugin;
-  DBUG_ENTER("ha_register_builtin_plugins");
-
-  for (hton= sys_table_types; *hton; hton++)
-    size+= sizeof(struct st_mysql_plugin);
-  
-  if (!(plugin= (struct st_mysql_plugin *)
-        my_once_alloc(size, MYF(MY_WME | MY_ZEROFILL))))
-    DBUG_RETURN(1);
-  
-  for (hton= sys_table_types; *hton; hton++, plugin++)
-  {
-    plugin->type= MYSQL_STORAGE_ENGINE_PLUGIN;
-    plugin->info= *hton;
-    plugin->version= 0;
-    plugin->name= (*hton)->name;
-    plugin->author= NULL;
-    plugin->descr= (*hton)->comment;
-    
-    if (plugin_register_builtin(plugin))
-      DBUG_RETURN(1);
-  }
-  DBUG_RETURN(0);
+  DBUG_RETURN(error);
 }
 
 
@@ -3270,10 +3264,11 @@ int handler::ha_external_lock(THD *thd, int lock_type)
     locking combined with row-based replication needs to be looked
     over. Ideally, no such special handling should be needed.
    */
-  switch (thd->lex->sql_command)
-  {
+  switch (thd->lex->sql_command) {
   case SQLCOM_TRUNCATE:
   case SQLCOM_ALTER_TABLE:
+  case SQLCOM_OPTIMIZE:
+  case SQLCOM_REPAIR:
     DBUG_RETURN(0);
   default:
     break;
diff --git a/sql/handler.h b/sql/handler.h
index 090ef1f9f30..d988e46b236 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -84,6 +84,7 @@
   access on the table based on a given record.
 */ 
 #define HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS (1 << 16) 
+#define HA_CAN_RTREEKEYS       (1 << 17)
 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
 #define HA_CAN_FULLTEXT        (1 << 21)
@@ -233,6 +234,7 @@ enum legacy_db_type
   DB_TYPE_BLACKHOLE_DB,
   DB_TYPE_PARTITION_DB,
   DB_TYPE_BINLOG,
+  DB_TYPE_FIRST_DYNAMIC=32,
   DB_TYPE_DEFAULT=127 // Must be last
 };
 
@@ -280,6 +282,7 @@ enum enum_binlog_command {
 #define HA_CREATE_USED_COMMENT          (1L << 16)
 #define HA_CREATE_USED_PASSWORD         (1L << 17)
 #define HA_CREATE_USED_CONNECTION       (1L << 18)
+#define HA_CREATE_USED_KEY_BLOCK_SIZE   (1L << 19)
 
 typedef ulonglong my_xid; // this line is the same as in log_event.h
 #define MYSQL_XID_PREFIX "MySQLXid"
@@ -653,6 +656,7 @@ typedef struct st_ha_create_information
   ulong table_options;
   ulong avg_row_length;
   ulong used_fields;
+  ulong key_block_size;
   SQL_LIST merge_list;
   handlerton *db_type;
   enum row_type row_type;
@@ -666,6 +670,15 @@ typedef struct st_ha_create_information
   bool store_on_disk;                   /* 1 if table stored on disk */
 } HA_CREATE_INFO;
 
+
+typedef struct st_key_create_information
+{
+  enum ha_key_alg algorithm;
+  ulong block_size;
+  LEX_STRING parser_name;
+} KEY_CREATE_INFO;
+
+
 /*
   Class for maintaining hooks used inside operations on tables such
   as: create table functions, delete table functions, and alter table
@@ -700,6 +713,7 @@ private:
 
 typedef struct st_savepoint SAVEPOINT;
 extern ulong savepoint_alloc_size;
+extern KEY_CREATE_INFO default_key_create_info;
 
 /* Forward declaration for condition pushdown to storage engine */
 typedef class Item COND;
@@ -1553,8 +1567,8 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
 
 /* basic stuff */
 int ha_init(void);
-int ha_register_builtin_plugins();
-int ha_initialize_handlerton(handlerton *hton);
+int ha_initialize_handlerton(st_plugin_int *plugin);
+int ha_finalize_handlerton(st_plugin_int *plugin);
 
 TYPELIB *ha_known_exts(void);
 int ha_panic(enum ha_panic_function flag);
diff --git a/sql/handlerton-win.cc b/sql/handlerton-win.cc
deleted file mode 100644
index 9ce4eab2444..00000000000
--- a/sql/handlerton-win.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "mysql_priv.h"
-
-extern handlerton heap_hton;
-extern handlerton myisam_hton;
-extern handlerton myisammrg_hton;
-extern handlerton binlog_hton;
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-extern handlerton innobase_hton;
-#endif
-#ifdef WITH_BERKELEY_STORAGE_ENGINE
-extern handlerton berkeley_hton;
-#endif
-#ifdef WITH_EXAMPLE_STORAGE_ENGINE
-extern handlerton example_hton;
-#endif
-#ifdef WITH_ARCHIVE_STORAGE_ENGINE
-extern handlerton archive_hton;
-#endif
-#ifdef WITH_CSV_STORAGE_ENGINE
-extern handlerton tina_hton;
-#endif
-#ifdef WITH_BLACKHOLE_STORAGE_ENGINE
-extern handlerton blackhole_hton;
-#endif
-#ifdef WITH_FEDERATED_STORAGE_ENGINE
-extern handlerton federated_hton;
-#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-extern handlerton ndbcluster_hton;
-#endif
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-extern handlerton partition_hton;
-#endif
-
-/*
-  This array is used for processing compiled in engines.
-*/
-handlerton *sys_table_types[]=
-{
-  &heap_hton,
-  &myisam_hton,
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  &innobase_hton,
-#endif
-#ifdef WITH_BERKELEY_STORAGE_ENGINE
-  &berkeley_hton,
-#endif
-#ifdef WITH_EXAMPLE_STORAGE_ENGINE
-  &example_hton,
-#endif
-#ifdef WITH_ARCHIVE_STORAGE_ENGINE
-  &archive_hton,
-#endif
-#ifdef WITH_CSV_STORAGE_ENGINE
-  &tina_hton,
-#endif
-#ifdef WITH_BLACKHOLE_STORAGE_ENGINE
-  &blackhole_hton,
-#endif
-#ifdef WITH_FEDERATED_STORAGE_ENGINE
-  &federated_hton,
-#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-  &ndbcluster_hton,
-#endif
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-  &partition_hton,
-#endif
-  &myisammrg_hton,
-  &binlog_hton,
-  NULL
-};
diff --git a/sql/handlerton.cc.in b/sql/handlerton.cc.in
deleted file mode 100644
index 55af8cdd8cf..00000000000
--- a/sql/handlerton.cc.in
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include "mysql_priv.h"
-
-extern handlerton heap_hton,myisam_hton,myisammrg_hton,
-  binlog_hton@mysql_se_decls@;
-
-/*
-  This array is used for processing compiled in engines.
-*/
-handlerton *sys_table_types[]=
-{
-  &heap_hton,&myisam_hton@mysql_se_htons@,&myisammrg_hton,&binlog_hton,NULL
-};
-
diff --git a/sql/item.cc b/sql/item.cc
index 6c79bb39369..f778f0cb38e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1998,6 +1998,16 @@ bool Item_decimal::eq(const Item *item, bool binary_cmp) const
 }
 
 
+void Item_decimal::set_decimal_value(my_decimal *value_par)
+{
+  my_decimal2decimal(value_par, &decimal_value);
+  decimals= (uint8) decimal_value.frac;
+  unsigned_flag= !decimal_value.sign();
+  max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
+                                             decimals, unsigned_flag);
+}
+
+
 String *Item_float::val_str(String *str)
 {
   // following assert is redundant, because fixed=1 assigned in constructor
@@ -3144,7 +3154,8 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
     both clauses contain different fields with the same names, a warning is
     issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no
     GROUP BY column is found, then a HAVING name is resolved as a possibly
-    derived SELECT column.
+    derived SELECT column. This extension is allowed only if the
+    MODE_ONLY_FULL_GROUP_BY sql mode isn't enabled.
 
   NOTES
     The resolution procedure is:
@@ -3154,7 +3165,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
       in the GROUP BY clause of Q.
     - If found different columns with the same name in GROUP BY and SELECT
       - issue a warning and return the GROUP BY column,
-      - otherwise return the found SELECT column.
+      - otherwise
+        - if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error
+        - else return the found SELECT column.
 
 
   RETURN
@@ -3199,6 +3212,17 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
     }
   }
 
+  if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
+      select_ref != not_found_item && !group_by_ref)
+  {
+    /*
+      Report the error if fields was found only in the SELECT item list and
+      the strict mode is enabled.
+    */
+    my_error(ER_NON_GROUPING_FIELD_USED, MYF(0),
+             ref->name, "HAVING");
+    return NULL;
+  }
   if (select_ref != not_found_item || group_by_ref)
   {
     if (select_ref != not_found_item && !ambiguous_fields)
@@ -5168,14 +5192,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
   return FALSE;
 }
 
-void Item_null_helper::print(String *str)
-{
-  str->append(STRING_WITH_LEN("("));
-  store->print(str);
-  str->append(')');
-}
-
-
 bool Item_default_value::eq(const Item *item, bool binary_cmp) const
 {
   return item->type() == DEFAULT_VALUE_ITEM && 
diff --git a/sql/item.h b/sql/item.h
index ffa3e09fc6e..f73017563dd 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1486,6 +1486,7 @@ public:
   }
   uint decimal_precision() const { return decimal_value.precision(); }
   bool eq(const Item *, bool binary_cmp) const;
+  void set_decimal_value(my_decimal *value_par);
 };
 
 
@@ -1892,21 +1893,6 @@ public:
   }
 };
 
-class Item_null_helper :public Item_ref_null_helper
-{
-  Item *store;
-public:
-  Item_null_helper(Name_resolution_context *context_arg,
-                   Item_in_subselect* master, Item *item,
-		   const char *table_name_arg, const char *field_name_arg)
-    :Item_ref_null_helper(context_arg, master, (store= 0, &store),
-                          table_name_arg, field_name_arg),
-     store(item)
-    { ref= &store; }
-  void print(String *str);
-};
-
-
 /*
   The following class is used to optimize comparing of date and bigint columns
   We need to save the original item ('ref') to be able to call
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 67f0a5f5e2e..1cfdcef02d0 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -623,15 +623,17 @@ public:
 
 /* Functions to handle the optimized IN */
 
+
+/* A vector of values of some type  */
+
 class in_vector :public Sql_alloc
 {
- protected:
+public:
   char *base;
   uint size;
   qsort2_cmp compare;
   CHARSET_INFO *collation;
   uint count;
-public:
   uint used_count;
   in_vector() {}
   in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
@@ -647,6 +649,32 @@ public:
     qsort2(base,used_count,size,compare,collation);
   }
   int find(Item *item);
+  
+  /* 
+    Create an instance of Item_{type} (e.g. Item_decimal) constant object
+    which type allows it to hold an element of this vector without any
+    conversions.
+    The purpose of this function is to be able to get elements of this
+    vector in form of Item_xxx constants without creating Item_xxx object
+    for every array element you get (i.e. this implements "FlyWeight" pattern)
+  */
+  virtual Item* create_item() { return NULL; }
+  
+  /*
+    Store the value at position #pos into provided item object
+    SYNOPSIS
+      value_to_item()
+        pos   Index of value to store
+        item  Constant item to store value into. The item must be of the same
+              type that create_item() returns.
+  */
+  virtual void value_to_item(uint pos, Item *item) { }
+  
+  /* Compare values number pos1 and pos2 for equality */
+  bool compare_elems(uint pos1, uint pos2)
+  {
+    return test(compare(collation, base + pos1*size, base + pos2*size));
+  }
 };
 
 class in_string :public in_vector
@@ -658,6 +686,16 @@ public:
   ~in_string();
   void set(uint pos,Item *item);
   byte *get_value(Item *item);
+  Item* create_item()
+  { 
+    return new Item_string(collation);
+  }
+  void value_to_item(uint pos, Item *item)
+  {    
+    String *str=((String*) base)+pos;
+    Item_string *to= (Item_string*)item;
+    to->str_value= *str;
+  }
 };
 
 class in_longlong :public in_vector
@@ -667,6 +705,19 @@ public:
   in_longlong(uint elements);
   void set(uint pos,Item *item);
   byte *get_value(Item *item);
+  
+  Item* create_item()
+  { 
+    /* 
+      We're created a signed INT, this may not be correct in 
+      general case (see BUG#19342).
+    */
+    return new Item_int((longlong)0);
+  }
+  void value_to_item(uint pos, Item *item)
+  {
+    ((Item_int*)item)->value= ((longlong*)base)[pos];
+  }
 };
 
 class in_double :public in_vector
@@ -676,6 +727,15 @@ public:
   in_double(uint elements);
   void set(uint pos,Item *item);
   byte *get_value(Item *item);
+  Item *create_item()
+  { 
+    return new Item_float(0.0);
+  }
+  void value_to_item(uint pos, Item *item)
+  {
+    ((Item_float*)item)->value= ((double*) base)[pos];
+  }
+
 };
 
 class in_decimal :public in_vector
@@ -685,6 +745,16 @@ public:
   in_decimal(uint elements);
   void set(uint pos, Item *item);
   byte *get_value(Item *item);
+  Item *create_item()
+  { 
+    return new Item_decimal(0, FALSE);
+  }
+  void value_to_item(uint pos, Item *item)
+  {
+    my_decimal *dec= ((my_decimal *)base) + pos;
+    Item_decimal *item_dec= (Item_decimal*)item;
+    item_dec->set_decimal_value(dec);
+  }
 };
 
 
@@ -864,12 +934,13 @@ public:
 
 class Item_func_in :public Item_func_opt_neg
 {
+public:
   Item_result cmp_type;
   in_vector *array;
   cmp_item *in_item;
   bool have_null;
   DTCollation cmp_collation;
- public:
+
   Item_func_in(List &list)
     :Item_func_opt_neg(list), array(0), in_item(0), have_null(0)
   {
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 2e4d469d2d2..9281a8a1ddf 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4559,12 +4559,6 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
   sys_var *var;
   LEX_STRING *base_name, *component_name;
 
-  if (component.str == 0 &&
-      !my_strcasecmp(system_charset_info, name.str, "VERSION"))
-    return new Item_string(NULL, server_version,
-			   (uint) strlen(server_version),
-			   system_charset_info, DERIVATION_SYSCONST);
-
   if (component.str)
   {
     base_name= &component;
diff --git a/sql/item_func.h b/sql/item_func.h
index ed5924e8fe1..a91d93be8c6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -284,6 +284,7 @@ class Item_func_connection_id :public Item_int_func
   longlong value;
 
 public:
+  Item_func_connection_id() {}
   const char *func_name() const { return "connection_id"; }
   void fix_length_and_dec();
   bool fix_fields(THD *thd, Item **ref);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 68f189ccf8c..6c2ff19825f 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -931,14 +931,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
   {
     Item *item= (Item*) select_lex->item_list.head();
 
-    select_lex->item_list.empty();
-    select_lex->item_list.push_back(new Item_int("Not_used",
-						 (longlong) 1, 21));
-    select_lex->ref_pointer_array[0]= select_lex->item_list.head();
     if (select_lex->table_list.elements)
     {
       bool tmp;
       Item *having= item, *orig_item= item;
+      select_lex->item_list.empty();
+      select_lex->item_list.push_back(new Item_int("Not_used",
+                                                   (longlong) 1, 21));
+      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
       item= func->create(expr, item);
       if (!abort_on_null && orig_item->maybe_null)
       {
@@ -993,17 +993,15 @@ Item_in_subselect::single_value_transformer(JOIN *join,
 	  comparison functions can't be changed during fix_fields()
 	  we can assign select_lex->having here, and pass 0 as last
 	  argument (reference) to fix_fields()
-        */
-        item= func->create(expr,
-                           new Item_null_helper(&select_lex->context,
-                                                this, item,
-                                                (char *)"",
-                                                (char *)""));
-#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
-        if (!abort_on_null && left_expr->maybe_null)
-          item= new Item_cond_or(new Item_func_isnull(left_expr), item);
-#endif
-	select_lex->having= join->having= item;
+	*/
+	select_lex->having=
+	  join->having=
+	  func->create(expr,
+                       new Item_ref_null_helper(&select_lex->context, this,
+                                            select_lex->ref_pointer_array,
+                                            (char *)"",
+                                            (char *)""));
+
 	select_lex->having_fix_field= 1;
         /*
           we do not check join->having->fixed, because comparison function
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index a245e3b1b33..17e8db90dc7 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2280,6 +2280,30 @@ static int my_xpath_parse_Number(MY_XPATH *xpath)
 }
 
 
+/*
+  QName grammar can be found in a separate document
+  http://www.w3.org/TR/REC-xml-names/#NT-QName
+
+  [6] 	QName     ::= (Prefix ':')? LocalPart
+  [7] 	Prefix    ::= NCName
+  [8] 	LocalPart ::= NCName
+*/
+static int
+my_xpath_parse_QName(MY_XPATH *xpath)
+{
+  const char *beg;
+  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
+    return 0;
+  beg= xpath->prevtok.beg;
+  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_COLON))
+    return 1; /* Non qualified name */
+  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
+    return 0;
+  xpath->prevtok.beg= beg;
+  return 1;
+}
+
+
 /*
   Scan Variable reference
 
@@ -2313,7 +2337,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath)
 static int
 my_xpath_parse_NodeTest_QName(MY_XPATH *xpath)
 {
-  if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
+  if (!my_xpath_parse_QName(xpath))
     return 0;
   DBUG_ASSERT(xpath->context);
   uint len= xpath->prevtok.end - xpath->prevtok.beg;
diff --git a/sql/lex.h b/sql/lex.h
index 171f7a48980..555a68dc388 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -275,6 +275,7 @@ static SYMBOL symbols[] = {
   { "JOIN",		SYM(JOIN_SYM)},
   { "KEY",		SYM(KEY_SYM)},
   { "KEYS",		SYM(KEYS)},
+  { "KEY_BLOCK_SIZE",	SYM(KEY_BLOCK_SIZE)},
   { "KILL",		SYM(KILL_SYM)},
   { "LANGUAGE",         SYM(LANGUAGE_SYM)},
   { "LAST",		SYM(LAST_SYM)},
diff --git a/sql/log.cc b/sql/log.cc
index 818abe89e02..7c8f314bc08 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -30,6 +30,8 @@
 #include "message.h"
 #endif
 
+#include 
+
 /* max size of the log message */
 #define MAX_LOG_BUFFER_SIZE 1024
 #define MAX_USER_HOST_SIZE 512
@@ -68,11 +70,15 @@ struct binlog_trx_data {
   Rows_log_event *pending;                // The pending binrows event
 };
 
+static const char binlog_hton_name[]= "binlog";
+static const char binlog_hton_comment[]=
+  "This is a meta storage engine to represent the binlog in a transaction";
+
 handlerton binlog_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "binlog",
+  binlog_hton_name,
   SHOW_OPTION_YES,
-  "This is a meta storage engine to represent the binlog in a transaction",
+  binlog_hton_comment,
   DB_TYPE_BINLOG,               /* IGNORE  for now */
   binlog_init,
   0,
@@ -1084,7 +1090,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev)
       were, we would have to ensure that we're not ending a statement
       inside a stored function.
      */
-    thd->binlog_flush_pending_rows_event(true);
+    thd->binlog_flush_pending_rows_event(TRUE);
     error= mysql_bin_log.write(thd, trans_log, end_ev);
   }
   else
@@ -1480,6 +1486,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
   return log_name;
 }
 
+
 bool MYSQL_LOG::open_index_file(const char *index_file_name_arg,
                                 const char *log_name)
 {
@@ -2872,23 +2879,27 @@ bool MYSQL_LOG::write(Log_event *event_info)
       binlog_trx_data *const trx_data=
         (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
       IO_CACHE *trans_log= &trx_data->trans_log;
+      bool trans_log_in_use= my_b_tell(trans_log) != 0;
 
-      if (event_info->get_cache_stmt() && !my_b_tell(trans_log))
+      if (event_info->get_cache_stmt() && !trans_log_in_use)
         trans_register_ha(thd,
-                          thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN),
+                          (thd->options &
+                           (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)),
                           &binlog_hton);
-
-      if (event_info->get_cache_stmt() || my_b_tell(trans_log))
+      if (event_info->get_cache_stmt() || trans_log_in_use)
+      {
+        DBUG_PRINT("info", ("Using trans_log"));
         file= trans_log;
+      }
       /*
-        Note: as Mats suggested, for all the cases above where we write to
+        TODO as Mats suggested, for all the cases above where we write to
         trans_log, it sounds unnecessary to lock LOCK_log. We should rather
         test first if we want to write to trans_log, and if not, lock
-        LOCK_log. TODO.
+        LOCK_log.
       */
     }
 #endif
-    DBUG_PRINT("info",("event type=%d",event_info->get_type_code()));
+    DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
 
     /*
       No check for auto events flag here - this write method should
@@ -4343,3 +4354,16 @@ err1:
   return 1;
 }
 
+
+mysql_declare_plugin(binlog)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &binlog_hton,
+  binlog_hton_name,
+  "MySQL AB",
+  binlog_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+}
+mysql_declare_plugin_end;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index bc398b3d20a..93db68d1b50 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -92,7 +92,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
   do {                                                                    \
     DBUG_ASSERT(strncmp(Ver, MYSQL_SERVER_VERSION, sizeof(Ver)-1) >= 0);  \
     push_warning_printf(((THD *)Thd), MYSQL_ERROR::WARN_LEVEL_WARN,       \
-                        ER_WARN_DEPRECATED, ER(ER_WARN_DEPRECATED),       \
+                        ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX),       \
                         (Old), (Ver), (New));                             \
   } while(0)
 
@@ -177,6 +177,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
 
 /* Characters shown for the command in 'show processlist' */
 #define PROCESS_LIST_WIDTH 100
+/* Characters shown for the command in 'information_schema.processlist' */
+#define PROCESS_LIST_INFO_WIDTH 65535
 
 /* Time handling defaults */
 #define TIMESTAMP_MAX_YEAR 2038
@@ -556,6 +558,7 @@ enum enum_mysql_completiontype {
 };
 
 bool begin_trans(THD *thd);
+bool end_active_trans(THD *thd);
 int end_trans(THD *thd, enum enum_mysql_completiontype completion);
 
 Item *negate_expression(THD *thd, Item *expr);
@@ -1363,8 +1366,8 @@ bool mysql_manager_submit(void (*action)());
 void print_where(COND *cond,const char *info);
 void print_cached_tables(void);
 void TEST_filesort(SORT_FIELD *sortorder,uint s_length);
-void print_plan(JOIN* join, double read_time, double record_count,
-                uint idx, const char *info);
+void print_plan(JOIN* join,uint idx, double record_count, double read_time,
+                double current_read_time, const char *info);
 #endif
 void mysql_print_status();
 /* key.cc */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4de1e95d0f3..0bae436cf78 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -742,6 +742,7 @@ static void clean_up_mutexes(void);
 static void wait_for_signal_thread_to_end(void);
 static int test_if_case_insensitive(const char *dir_name);
 static void create_pid_file();
+static void end_ssl();
 
 #ifndef EMBEDDED_LIBRARY
 /****************************************************************************
@@ -1184,8 +1185,8 @@ void clean_up(bool print_message)
 #ifdef HAVE_DLOPEN
     udf_free();
 #endif
-    plugin_free();
   }
+  plugin_free();
   if (tc_log)
     tc_log->close();
   xid_cache_free();
@@ -1217,10 +1218,7 @@ void clean_up(bool print_message)
 #endif
   delete binlog_filter;
   delete rpl_filter;
-#ifdef HAVE_OPENSSL
-  if (ssl_acceptor_fd)
-    my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
-#endif /* HAVE_OPENSSL */
+  end_ssl();
 #ifdef USE_REGEX
   my_regex_end();
 #endif
@@ -2637,12 +2635,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
     return 1;
   }
 
-  if (ha_register_builtin_plugins())
-  {
-    sql_print_error("Failed to register built-in storage engines.");
-    return 1;
-  }
-
   load_defaults(conf_file_name, groups, &argc, &argv);
   defaults_argv=argv;
   get_options(argc,argv);
@@ -2968,6 +2960,18 @@ static void init_ssl()
 }
 
 
+static void end_ssl()
+{
+#ifdef HAVE_OPENSSL
+  if (ssl_acceptor_fd)
+  {
+    free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
+    ssl_acceptor_fd= 0;
+  }
+#endif /* HAVE_OPENSSL */
+}
+
+
 static int init_server_components()
 {
   DBUG_ENTER("init_server_components");
@@ -3012,42 +3016,13 @@ static int init_server_components()
     }
   }
 
-#ifdef WITH_CSV_STORAGE_ENGINE
-  if (opt_bootstrap)
-    log_output_options= LOG_FILE;
-  else
-    logger.init_log_tables();
-
-  if (log_output_options & LOG_NONE)
+  if (xid_cache_init())
   {
-    /*
-      Issue a warining if there were specified additional options to the
-      log-output along with NONE. Probably this wasn't what user wanted.
-    */
-    if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
-      sql_print_warning("There were other values specified to "
-                        "log-output besides NONE. Disabling slow "
-                        "and general logs anyway.");
-    logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
+    sql_print_error("Out of memory");
+    unireg_abort(1);
   }
-  else
-  {
-    /* fall back to the log files if tables are not present */
-    if (have_csv_db == SHOW_OPTION_NO)
-    {
-      sql_print_error("CSV engine is not present, falling back to the "
-                      "log files");
-      log_output_options= log_output_options & ~LOG_TABLE | LOG_FILE;
-    }
-
-    logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
-                        opt_log ? log_output_options:LOG_NONE);
-  }
-#else
-  logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
-                      opt_log ? LOG_FILE:LOG_NONE);
-#endif
 
+  /* need to configure logging before initializing storage engines */
   if (opt_update_log)
   {
     /*
@@ -3175,17 +3150,49 @@ server.");
     using_update_log=1;
   }
 
-  if (xid_cache_init())
-  {
-    sql_print_error("Out of memory");
-    unireg_abort(1);
-  }
+  /* We have to initialize the storage engines before CSV logging */
   if (ha_init())
   {
     sql_print_error("Can't init databases");
     unireg_abort(1);
   }
 
+#ifdef WITH_CSV_STORAGE_ENGINE
+  if (opt_bootstrap)
+    log_output_options= LOG_FILE;
+  else
+    logger.init_log_tables();
+
+  if (log_output_options & LOG_NONE)
+  {
+    /*
+      Issue a warining if there were specified additional options to the
+      log-output along with NONE. Probably this wasn't what user wanted.
+    */
+    if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
+      sql_print_warning("There were other values specified to "
+                        "log-output besides NONE. Disabling slow "
+                        "and general logs anyway.");
+    logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
+  }
+  else
+  {
+    /* fall back to the log files if tables are not present */
+    if (have_csv_db == SHOW_OPTION_NO)
+    {
+      sql_print_error("CSV engine is not present, falling back to the "
+                      "log files");
+      log_output_options= log_output_options & ~LOG_TABLE | LOG_FILE;
+    }
+
+    logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
+                        opt_log ? log_output_options:LOG_NONE);
+  }
+#else
+  logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
+                      opt_log ? LOG_FILE:LOG_NONE);
+#endif
+
   /*
     Check that the default storage engine is actually available.
   */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 3fddd780171..e4eb6e8ab3f 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4695,17 +4695,92 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
 
     if (inv)
     {
-      tree= get_ne_mm_tree(param, cond_func, field,
-                           func->arguments()[1], func->arguments()[1],
-                           cmp_type);
-      if (tree)
+      /*
+        We get here for conditions like "t.keypart NOT IN (....)".
+        
+        If the IN-list contains only constants (and func->array is an ordered
+        array of them), we construct the appropriate SEL_ARG tree manually, 
+        because constructing it using the range analyzer (as 
+        AND_i( t.keypart != c_i)) will cause lots of memory to be consumed
+        (see BUG#15872). 
+      */
+      if (func->array && func->cmp_type != ROW_RESULT)
       {
-        Item **arg, **end;
-        for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
-             arg < end ; arg++)
+        /* 
+          Create one Item_type constant object. We'll need it as
+          get_mm_parts only accepts constant values wrapped in Item_Type
+          objects.
+          We create the Item on param->mem_root which points to
+          per-statement mem_root (while thd->mem_root is currently pointing
+          to mem_root local to range optimizer).
+        */
+        MEM_ROOT *tmp_root= param->mem_root;
+        param->thd->mem_root= param->old_root;
+        Item *value_item= func->array->create_item();
+        param->thd->mem_root= tmp_root;
+
+        if (!value_item)
+          break;
+        
+        /* Get a SEL_TREE for "-inf < X < c_0" interval */
+        func->array->value_to_item(0, value_item);
+        tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
+                           value_item, cmp_type);
+        if (!tree)
+          break;
+#define NOT_IN_IGNORE_THRESHOLD 1000        
+        SEL_TREE *tree2;
+        if (func->array->count < NOT_IN_IGNORE_THRESHOLD)
         {
-          tree=  tree_and(param, tree, get_ne_mm_tree(param, cond_func, field, 
-                                                      *arg, *arg, cmp_type));
+          for (uint i=1; i < func->array->count; i++)
+          {
+            if (func->array->compare_elems(i, i-1))
+            {
+              /* Get a SEL_TREE for "-inf < X < c_i" interval */
+              func->array->value_to_item(i, value_item);
+              tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
+                                  value_item, cmp_type);
+              
+              /* Change all intervals to be "c_{i-1} < X < c_i" */
+              for (uint idx= 0; idx < param->keys; idx++)
+              {
+                SEL_ARG *new_interval;
+                if ((new_interval=  tree2->keys[idx]))
+                {
+                  SEL_ARG *last_val= tree->keys[idx]->last();
+                  new_interval->min_value= last_val->max_value;
+                  new_interval->min_flag= NEAR_MIN;
+                }
+              }
+              tree= tree_or(param, tree, tree2);
+            }
+          }
+        }
+        else
+          func->array->value_to_item(func->array->count - 1, value_item);
+
+        /* 
+          Get the SEL_TREE for the last "c_last < X < +inf" interval 
+          (value_item cotains c_last already)
+        */
+        tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
+                            value_item, cmp_type);
+        tree= tree_or(param, tree, tree2);
+      }
+      else
+      {
+        tree= get_ne_mm_tree(param, cond_func, field,
+                             func->arguments()[1], func->arguments()[1],
+                             cmp_type);
+        if (tree)
+        {
+          Item **arg, **end;
+          for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
+               arg < end ; arg++)
+          {
+            tree=  tree_and(param, tree, get_ne_mm_tree(param, cond_func, field, 
+                                                        *arg, *arg, cmp_type));
+          }
         }
       }
     }
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index dfc5dd2989b..6761b28331e 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -21,9 +21,10 @@
 #endif
 
 #include "mysql_priv.h"
-#include "ha_partition.h"
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
+#include "ha_partition.h"
+
 
 partition_info *partition_info::get_clone()
 {
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index e207a0bf633..9cabe1a3df0 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -861,7 +861,8 @@ bool load_master_data(THD* thd)
 
       if (!rpl_filter->db_ok(db) || 
 	  !rpl_filter->db_ok_with_wild_table(db) || 
-	  !strcmp(db,"mysql"))
+	  !strcmp(db,"mysql") ||
+          is_schema_db(db))
       {
 	*cur_table_res = 0;
 	continue;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 16a0c752639..ae45b299196 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -438,6 +438,8 @@ sys_var_thd_storage_engine sys_storage_engine("storage_engine",
 sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period);
 #endif
 sys_var_bool_ptr	sys_sync_frm("sync_frm", &opt_sync_frm);
+sys_var_const_str	sys_system_time_zone("system_time_zone",
+                                             system_time_zone);
 sys_var_long_ptr	sys_table_def_size("table_definition_cache",
                                            &table_def_size);
 sys_var_long_ptr	sys_table_cache_size("table_open_cache",
@@ -455,6 +457,13 @@ sys_var_thd_ulong	sys_tmp_table_size("tmp_table_size",
 					   &SV::tmp_table_size);
 sys_var_bool_ptr  sys_timed_mutexes("timed_mutexes",
                                     &timed_mutexes);
+sys_var_const_str	sys_version("version", server_version);
+sys_var_const_str	sys_version_comment("version_comment",
+                                            MYSQL_COMPILATION_COMMENT);
+sys_var_const_str	sys_version_compile_machine("version_compile_machine",
+                                                    MACHINE_TYPE);
+sys_var_const_str	sys_version_compile_os("version_compile_os",
+                                               SYSTEM_TYPE);
 sys_var_thd_ulong	sys_net_wait_timeout("wait_timeout",
 					     &SV::net_wait_timeout);
 
@@ -622,7 +631,6 @@ sys_var_thd_time_zone            sys_time_zone("time_zone");
 
 /* Read only variables */
 
-sys_var_const_str		sys_os("version_compile_os", SYSTEM_TYPE);
 sys_var_have_variable sys_have_archive_db("have_archive", &have_archive_db);
 sys_var_have_variable sys_have_berkeley_db("have_bdb", &have_berkeley_db);
 sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine",
@@ -630,7 +638,7 @@ sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine",
 sys_var_have_variable sys_have_compress("have_compress", &have_compress);
 sys_var_have_variable sys_have_crypt("have_crypt", &have_crypt);
 sys_var_have_variable sys_have_csv_db("have_csv", &have_csv_db);
-sys_var_have_variable sys_have_dlopen("have_dlopen", &have_dlopen);
+sys_var_have_variable sys_have_dlopen("have_dynamic_loading", &have_dlopen);
 sys_var_have_variable sys_have_example_db("have_example_engine",
                                           &have_example_db);
 sys_var_have_variable sys_have_federated_db("have_federated_engine",
@@ -902,9 +910,9 @@ SHOW_VAR init_vars[]= {
    SHOW_SYS},
   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
   {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
-  {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS},
   {"port",                    (char*) &mysqld_port,                  SHOW_INT},
   {sys_preload_buff_size.name, (char*) &sys_preload_buff_size,      SHOW_SYS},
+  {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS},
   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
   {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
    SHOW_SYS},
@@ -949,10 +957,11 @@ SHOW_VAR init_vars[]= {
 #ifdef HAVE_SYS_UN_H
   {"socket",                  (char*) &mysqld_unix_port,             SHOW_CHAR_PTR},
 #endif
-  {sys_sort_buffer.name,      (char*) &sys_sort_buffer, 	    SHOW_SYS},
+  {sys_sort_buffer.name,      (char*) &sys_sort_buffer,             SHOW_SYS},
+  {sys_big_selects.name,      (char*) &sys_big_selects,             SHOW_SYS},
   {sys_sql_mode.name,         (char*) &sys_sql_mode,                SHOW_SYS},
-  {"sql_notes",               (char*) &sys_sql_notes,               SHOW_BOOL},
-  {"sql_warnings",            (char*) &sys_sql_warnings,            SHOW_BOOL},
+  {"sql_notes",               (char*) &sys_sql_notes,               SHOW_SYS},
+  {"sql_warnings",            (char*) &sys_sql_warnings,            SHOW_SYS},
   {sys_storage_engine.name,   (char*) &sys_storage_engine,          SHOW_SYS},
 #ifdef HAVE_REPLICATION
   {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period,     SHOW_SYS},
@@ -981,10 +990,11 @@ SHOW_VAR init_vars[]= {
   {sys_tx_isolation.name,     (char*) &sys_tx_isolation,	    SHOW_SYS},
   {sys_updatable_views_with_limit.name,
                               (char*) &sys_updatable_views_with_limit,SHOW_SYS},
-  {"version",                 server_version,                       SHOW_CHAR},
-  {"version_comment",         (char*) MYSQL_COMPILATION_COMMENT,    SHOW_CHAR},
-  {"version_compile_machine", (char*) MACHINE_TYPE,		    SHOW_CHAR},
-  {sys_os.name,		      (char*) &sys_os,			    SHOW_SYS},
+  {sys_version.name,          (char*) &sys_version,                 SHOW_SYS},
+  {sys_version_comment.name,  (char*) &sys_version_comment,         SHOW_SYS},
+  {sys_version_compile_machine.name, (char*) &sys_version_compile_machine,
+   SHOW_SYS},
+  {sys_version_compile_os.name,	(char*) &sys_version_compile_os,    SHOW_SYS},
   {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout,	    SHOW_SYS},
   {NullS, NullS, SHOW_LONG}
 };
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index c63c5f21a54..a2bc77714bb 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -2978,52 +2978,52 @@ ER_UDF_EXISTS
 	swe "Funktionen '%-.64s' finns redan"
 	ukr "æÕÎËÃ¦Ñ '%-.64s' ×ÖÅ ¦ÓÎÕ¤"
 ER_CANT_OPEN_LIBRARY  
-	cze "Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %s)"
-	dan "Kan ikke åbne delt bibliotek '%-.64s' (errno: %d %s)"
-	nla "Kan shared library '%-.64s' niet openen (Errcode: %d %s)"
-	eng "Can't open shared library '%-.64s' (errno: %d %s)"
-	jps "shared library '%-.64s' ‚ðŠJ‚­Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d %s)",
-	est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %s)"
-	fre "Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %s)"
-	ger "Kann Shared Library '%-.64s' nicht öffnen (Fehler: %d %s)"
-	greek "Äåí åßíáé äõíáôÞ ç áíÜãíùóç ôçò shared library '%-.64s' (êùäéêüò ëÜèïõò: %d %s)"
-	hun "A(z) '%-.64s' megosztott konyvtar nem hasznalhato (hibakod: %d %s)"
-	ita "Impossibile aprire la libreria condivisa '%-.64s' (errno: %d %s)"
-	jpn "shared library '%-.64s' ¤ò³«¤¯»ö¤¬¤Ç¤­¤Þ¤»¤ó (errno: %d %s)"
-	kor "'%-.64s' °øÀ¯ ¶óÀ̹ö·¯¸®¸¦ ¿­¼ö ¾ø½À´Ï´Ù.(¿¡·¯¹øÈ£: %d %s)"
-	nor "Can't open shared library '%-.64s' (errno: %d %s)"
-	norwegian-ny "Can't open shared library '%-.64s' (errno: %d %s)"
-	pol "Can't open shared library '%-.64s' (errno: %d %s)"
-	por "Não pode abrir biblioteca compartilhada '%-.64s' (erro no. '%d' - '%-.64s')"
-	rum "Nu pot deschide libraria shared '%-.64s' (Eroare: %d %s)"
-	rus "îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÄÉÎÁÍÉÞÅÓËÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ÏÛÉÂËÁ: %d %s)"
-	serbian "Ne mogu da otvorim share-ovanu biblioteku '%-.64s' (errno: %d %s)"
-	slo "Nemô¾em otvori» zdieµanú kni¾nicu '%-.64s' (chybový kód: %d %s)"
-	spa "No puedo abrir libraria conjugada '%-.64s' (errno: %d %s)"
-	swe "Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %s)"
-	ukr "îÅ ÍÏÖÕ ×¦ÄËÒÉÔÉ ÒÏÚĦÌÀ×ÁÎÕ Â¦Â̦ÏÔÅËÕ '%-.64s' (ÐÏÍÉÌËÁ: %d %s)"
-ER_CANT_FIND_DL_ENTRY  
-	cze "Nemohu naj-Bít funkci '%-.64s' v knihovnì"
-	dan "Kan ikke finde funktionen '%-.64s' i bibliotek"
-	nla "Kan functie '%-.64s' niet in library vinden"
-	eng "Can't find symbol '%-.64s' in library"
-	jps "function '%-.64s' ‚ðƒ‰ƒCƒuƒ‰ƒŠ[’†‚ÉŒ©•t‚¯‚鎖‚ª‚Å‚«‚Ü‚¹‚ñ",
-	est "Ei leia funktsiooni '%-.64s' antud teegis"
-	fre "Impossible de trouver la fonction '%-.64s' dans la bibliothèque"
-	ger "Kann Funktion '%-.64s' in der Library nicht finden"
-	greek "Äåí åßíáé äõíáôÞ ç áíåýñåóç ôçò óõíÜñôçóçò '%-.64s' óôçí âéâëéïèÞêç"
-	hun "A(z) '%-.64s' fuggveny nem talalhato a konyvtarban"
-	ita "Impossibile trovare la funzione '%-.64s' nella libreria"
-	jpn "function '%-.64s' ¤ò¥é¥¤¥Ö¥é¥ê¡¼Ãæ¤Ë¸«ÉÕ¤±¤ë»ö¤¬¤Ç¤­¤Þ¤»¤ó"
-	kor "¶óÀ̹ö·¯¸®¿¡¼­ '%-.64s' ÇÔ¼ö¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù."
-	por "Não pode encontrar a função '%-.64s' na biblioteca"
-	rum "Nu pot gasi functia '%-.64s' in libraria"
-	rus "îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÓÉÍ×ÏÌ '%-.64s' × ÂÉÂÌÉÏÔÅËÅ"
-	serbian "Ne mogu da pronadjem funkciju '%-.64s' u biblioteci"
-	slo "Nemô¾em nájs» funkciu '%-.64s' v kni¾nici"
-	spa "No puedo encontrar función '%-.64s' en libraria"
-	swe "Hittar inte funktionen '%-.64s' in det dynamiska biblioteket"
-	ukr "îÅ ÍÏÖÕ ÚÎÁÊÔÉ ÆÕÎËæÀ '%-.64s' Õ Â¦Â̦ÏÔÅæ"
+	cze "Nemohu otev-Bøít sdílenou knihovnu '%-.64s' (errno: %d %-.128s)"
+	dan "Kan ikke åbne delt bibliotek '%-.64s' (errno: %d %-.128s)"
+	nla "Kan shared library '%-.64s' niet openen (Errcode: %d %-.128s)"
+	eng "Can't open shared library '%-.64s' (errno: %d %-.128s)"
+	jps "shared library '%-.64s' ‚ðŠJ‚­Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d %-.128s)",
+	est "Ei suuda avada jagatud teeki '%-.64s' (veakood: %d %-.128s)"
+	fre "Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %-.128s)"
+	ger "Kann Shared Library '%-.64s' nicht öffnen (Fehler: %d %-.128s)"
+	greek "Äåí åßíáé äõíáôÞ ç áíÜãíùóç ôçò shared library '%-.64s' (êùäéêüò ëÜèïõò: %d %-.128s)"
+	hun "A(z) '%-.64s' megosztott konyvtar nem hasznalhato (hibakod: %d %-.128s)"
+	ita "Impossibile aprire la libreria condivisa '%-.64s' (errno: %d %-.128s)"
+	jpn "shared library '%-.64s' ¤ò³«¤¯»ö¤¬¤Ç¤­¤Þ¤»¤ó (errno: %d %-.128s)"
+	kor "'%-.64s' °øÀ¯ ¶óÀ̹ö·¯¸®¸¦ ¿­¼ö ¾ø½À´Ï´Ù.(¿¡·¯¹øÈ£: %d %-.128s)"
+	nor "Can't open shared library '%-.64s' (errno: %d %-.128s)"
+	norwegian-ny "Can't open shared library '%-.64s' (errno: %d %-.128s)"
+	pol "Can't open shared library '%-.64s' (errno: %d %-.128s)"
+	por "Não pode abrir biblioteca compartilhada '%-.64s' (erro no. %d '%-.128s')"
+	rum "Nu pot deschide libraria shared '%-.64s' (Eroare: %d %-.128s)"
+	rus "îÅ×ÏÚÍÏÖÎÏ ÏÔËÒÙÔØ ÄÉÎÁÍÉÞÅÓËÕÀ ÂÉÂÌÉÏÔÅËÕ '%-.64s' (ÏÛÉÂËÁ: %d %-.128s)"
+	serbian "Ne mogu da otvorim share-ovanu biblioteku '%-.64s' (errno: %d %-.128s)"
+	slo "Nemô¾em otvori» zdieµanú kni¾nicu '%-.64s' (chybový kód: %d %-.128s)"
+	spa "No puedo abrir libraria conjugada '%-.64s' (errno: %d %-.128s)"
+	swe "Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %-.128s)"
+	ukr "îÅ ÍÏÖÕ ×¦ÄËÒÉÔÉ ÒÏÚĦÌÀ×ÁÎÕ Â¦Â̦ÏÔÅËÕ '%-.64s' (ÐÏÍÉÌËÁ: %d %-.128s)"
+ER_CANT_FIND_DL_ENTRY
+	cze "Nemohu naj-Bít funkci '%-.128s' v knihovnì"
+	dan "Kan ikke finde funktionen '%-.128s' i bibliotek"
+	nla "Kan functie '%-.128s' niet in library vinden"
+	eng "Can't find symbol '%-.128s' in library"
+	jps "function '%-.128s' ‚ðƒ‰ƒCƒuƒ‰ƒŠ[’†‚ÉŒ©•t‚¯‚鎖‚ª‚Å‚«‚Ü‚¹‚ñ",
+	est "Ei leia funktsiooni '%-.128s' antud teegis"
+	fre "Impossible de trouver la fonction '%-.128s' dans la bibliothèque"
+	ger "Kann Funktion '%-.128s' in der Library nicht finden"
+	greek "Äåí åßíáé äõíáôÞ ç áíåýñåóç ôçò óõíÜñôçóçò '%-.128s' óôçí âéâëéïèÞêç"
+	hun "A(z) '%-.128s' fuggveny nem talalhato a konyvtarban"
+	ita "Impossibile trovare la funzione '%-.128s' nella libreria"
+	jpn "function '%-.128s' ¤ò¥é¥¤¥Ö¥é¥ê¡¼Ãæ¤Ë¸«ÉÕ¤±¤ë»ö¤¬¤Ç¤­¤Þ¤»¤ó"
+	kor "¶óÀ̹ö·¯¸®¿¡¼­ '%-.128s' ÇÔ¼ö¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù."
+	por "Não pode encontrar a função '%-.128s' na biblioteca"
+	rum "Nu pot gasi functia '%-.128s' in libraria"
+	rus "îÅ×ÏÚÍÏÖÎÏ ÏÔÙÓËÁÔØ ÓÉÍ×ÏÌ '%-.128s' × ÂÉÂÌÉÏÔÅËÅ"
+	serbian "Ne mogu da pronadjem funkciju '%-.128s' u biblioteci"
+	slo "Nemô¾em nájs» funkciu '%-.128s' v kni¾nici"
+	spa "No puedo encontrar función '%-.128s' en libraria"
+	swe "Hittar inte funktionen '%-.128s' in det dynamiska biblioteket"
+	ukr "îÅ ÍÏÖÕ ÚÎÁÊÔÉ ÆÕÎËæÀ '%-.128s' Õ Â¦Â̦ÏÔÅæ"
 ER_FUNCTION_NOT_DEFINED  
 	cze "Funkce '%-.64s' nen-Bí definována"
 	dan "Funktionen '%-.64s' er ikke defineret"
@@ -5602,6 +5602,22 @@ ER_SP_RECURSION_LIMIT
         ger "Rekursionsgrenze %d (durch Variable max_sp_recursion_depth gegeben) wurde für Routine %.64s überschritten"
 ER_SP_PROC_TABLE_CORRUPT
 	eng "Failed to load routine %-.64s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
+ER_SP_WRONG_NAME 42000
+	eng "Incorrect routine name '%-.64s'"
+ER_TABLE_NEEDS_UPGRADE
+         eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
+ER_SP_NO_AGGREGATE 42000
+	eng "AGGREGATE is not supported for stored functions"
+ER_MAX_PREPARED_STMT_COUNT_REACHED 42000
+        eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)"
+ER_VIEW_RECURSIVE
+        eng "`%-.64s`.`%-.64s` contains view recursion"
+ER_NON_GROUPING_FIELD_USED 42000
+	eng "non-grouping field '%-.64s' is used in %-.64s clause"
+ER_TABLE_CANT_HANDLE_SPKEYS
+        eng "The used table type doesn't support SPATIAL indexes"
+ER_ILLEGAL_HA_CREATE_OPTION
+        eng "Table storage engine '%-.64s' does not support the create option '%.64s'"
 ER_PARTITION_REQUIRES_VALUES_ERROR
         eng "%-.64s PARTITIONING requires definition of VALUES %-.64s for each partition"
         swe "%-.64s PARTITIONering kräver definition av VALUES %-.64s för varje partition"
@@ -5798,26 +5814,16 @@ ER_EVENT_DATA_TOO_LONG
 ER_DROP_INDEX_FK
         eng "Cannot drop index '%-.64s': needed in a foreign key constraint"
         ger "Kann Index '%-.64s' nicht löschen: wird für einen Fremdschlüssel benötigt"
+ER_WARN_DEPRECATED_SYNTAX  
+        eng  "The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead."
 ER_CANT_WRITE_LOCK_LOG_TABLE
         eng "You can't write-lock a log table. Only read access is possible."
 ER_CANT_READ_LOCK_LOG_TABLE
         eng "You can't use usual read lock with log tables. Try READ LOCAL instead."
-ER_SP_WRONG_NAME 42000
-	eng "Incorrect routine name '%-.64s'"
 ER_FOREIGN_DUPLICATE_KEY 23000 S1009
 	eng "Upholding foreign key constraints for table '%.64s', entry '%-.64s', key %d would lead to a duplicate entry"
 ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE
         eng "Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use scripts/mysql_fix_privilege_tables"
-ER_TABLE_NEEDS_UPGRADE
-         eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
-ER_ILLEGAL_HA_CREATE_OPTION
-        eng "Table storage engine '%-.64s' does not support the create option '%.64s'"
-ER_CANT_CHANGE_TX_ISOLATION 25001
-	eng "Transaction isolation level can't be changed while a transaction is in progress"
-ER_WARN_DEPRECATED
-        eng  "The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead."
-ER_SP_NO_AGGREGATE 42000
-	eng "AGGREGATE is not supported for stored functions"
 ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
 	eng "Cannot switch out of the row-based binary log format when the session has open temporary tables"
 ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
@@ -5834,7 +5840,5 @@ ER_NULL_IN_VALUES_LESS_THAN
 ER_WRONG_PARTITION_NAME
         eng "Incorrect partition name"
         swe "Felaktigt partitionsnamn"
-ER_MAX_PREPARED_STMT_COUNT_REACHED 42000
-        eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)"
-ER_VIEW_RECURSIVE
-        eng "`%-.64s`.`%-.64s` contain view recursion"
+ER_CANT_CHANGE_TX_ISOLATION 25001
+	eng "Transaction isolation level can't be changed while a transaction is in progress"
diff --git a/sql/sp.cc b/sql/sp.cc
index f7a6772146d..6f074fd7dce 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -268,7 +268,6 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
 static int
 db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
 {
-  extern int MYSQLparse(void *thd);
   TABLE *table;
   const char *params, *returns, *body;
   int ret;
@@ -477,6 +476,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
     (*sphp)->optimize();
   }
 end:
+  lex_end(thd->lex);
   thd->spcont= old_spcont;
   thd->variables.sql_mode= old_sql_mode;
   thd->variables.select_limit= old_select_limit;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index fbdb9a72640..8a64799e5f9 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -680,6 +680,7 @@ sp_head::destroy()
   DBUG_ASSERT(m_lex.is_empty() || m_thd);
   while ((lex= (LEX *)m_lex.pop()))
   {
+    lex_end(m_thd->lex);
     delete m_thd->lex;
     m_thd->lex= lex;
   }
@@ -1682,7 +1683,10 @@ sp_head::restore_lex(THD *thd)
   */
   merge_table_list(thd, sublex->query_tables, sublex);
   if (! sublex->sp_lex_in_use)
+  {
+    lex_end(sublex);
     delete sublex;
+  }
   thd->lex= oldlex;
   DBUG_VOID_RETURN;
 }
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 6b32ea13e5d..fbc277b4de8 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -521,7 +521,10 @@ public:
   virtual ~sp_lex_keeper()
   {
     if (m_lex_resp)
+    {
+      lex_end(m_lex);
       delete m_lex;
+    }
   }
 
   /*
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 010245cc077..77d2b165881 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -288,13 +288,13 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
 
   if (!(share= alloc_table_share(table_list, key, key_length)))
   {
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
     pthread_mutex_unlock(&LOCK_open);
 #endif
     DBUG_RETURN(0);
   }
 
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
   // We need a write lock to be able to add a new entry
   pthread_mutex_unlock(&LOCK_open);
   pthread_mutex_lock(&LOCK_open);
@@ -331,19 +331,19 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
 
   if (my_hash_insert(&table_def_cache, (byte*) share))
   {
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
     pthread_mutex_unlock(&LOCK_open);    
     (void) pthread_mutex_unlock(&share->mutex);
 #endif
     free_table_share(share);
     DBUG_RETURN(0);				// return error
   }
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
   pthread_mutex_unlock(&LOCK_open);
 #endif
   if (open_table_def(thd, share, db_flags))
   {
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
     /*
       No such table or wrong table definition file
       Lock first the table cache and then the mutex.
@@ -372,7 +372,7 @@ found:
 
   /* We must do a lock to ensure that the structure is initialized */
   (void) pthread_mutex_lock(&share->mutex);
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
   pthread_mutex_unlock(&LOCK_open);
 #endif
   if (share->error)
@@ -540,7 +540,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
   DBUG_VOID_RETURN;
 
 
-#ifdef NOT_YET
+#ifdef WAITING_FOR_TABLE_DEF_CACHE_STAGE_3
   if (to_be_deleted)
   {
     /*
@@ -1069,7 +1069,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
       handled either before writing a query log event (inside
       binlog_query()) or when preparing a pending event.
      */
-    thd->binlog_flush_pending_rows_event(true);
+    thd->binlog_flush_pending_rows_event(TRUE);
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in
new file mode 100644
index 00000000000..18705aa3dfb
--- /dev/null
+++ b/sql/sql_builtin.cc.in
@@ -0,0 +1,13 @@
+
+#include 
+
+typedef struct st_mysql_plugin builtin_plugin[];
+
+extern builtin_plugin 
+  builtin_binlog_plugin@mysql_plugin_defs@;
+
+struct st_mysql_plugin *mysqld_builtins[]=
+{
+  builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+};
+
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 0173b15ea68..6166771e5d1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2688,8 +2688,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
   DBUG_ENTER("THD::binlog_query");
   DBUG_ASSERT(query && mysql_bin_log.is_open());
 
-  switch (qtype)
-  {
+  switch (qtype) {
   case THD::MYSQL_QUERY_TYPE:
     /*
       Using this query type is a conveniece hack, since we have been
diff --git a/sql/sql_class.h b/sql/sql_class.h
index fdb70b6c991..54f256997d0 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -112,17 +112,16 @@ class Key :public Sql_alloc {
 public:
   enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY};
   enum Keytype type;
-  enum ha_key_alg algorithm;
+  KEY_CREATE_INFO key_create_info;
   List columns;
   const char *name;
   bool generated;
-  LEX_STRING *parser_name;
 
-  Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par,
-      bool generated_arg, List &cols,
-      LEX_STRING *parser_arg= 0)
-    :type(type_par), algorithm(alg_par), columns(cols), name(name_arg),
-    generated(generated_arg), parser_name(parser_arg)
+  Key(enum Keytype type_par, const char *name_arg,
+      KEY_CREATE_INFO *key_info_arg,
+      bool generated_arg, List &cols)
+    :type(type_par), key_create_info(*key_info_arg), columns(cols),
+    name(name_arg), generated(generated_arg)
   {}
   ~Key() {}
   /* Equality comparison of keys (ignoring name) */
@@ -144,7 +143,7 @@ public:
   foreign_key(const char *name_arg, List &cols,
 	      Table_ident *table,   List &ref_cols,
 	      uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
-    :Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, 0, cols),
+    :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
     ref_table(table), ref_columns(cols),
     delete_opt(delete_opt_arg), update_opt(update_opt_arg),
     match_opt(match_opt_arg)
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 4365d5b04ce..44b0fe1a2f1 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -21,7 +21,9 @@
 */
 
 #include "mysql_priv.h"
+#ifdef WITH_INNOBASE_STORAGE_ENGINE
 #include "ha_innodb.h"
+#endif
 #include "sql_select.h"
 #include "sp_head.h"
 #include "sql_trigger.h"
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5a76066af8c..562224201e7 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -168,8 +168,6 @@ void lex_start(THD *thd, const uchar *buf, uint length)
   lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
   lex->select_lex.group_list.empty();
   lex->select_lex.order_list.empty();
-  lex->current_select= &lex->select_lex;
-  lex->yacc_yyss=lex->yacc_yyvs=0;
   lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
   lex->sql_command= lex->orig_sql_command= SQLCOM_END;
   lex->duplicates= DUP_ERROR;
@@ -197,8 +195,16 @@ void lex_start(THD *thd, const uchar *buf, uint length)
 
 void lex_end(LEX *lex)
 {
-  x_free(lex->yacc_yyss);
-  x_free(lex->yacc_yyvs);
+  DBUG_ENTER("lex_end");
+  DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
+  if (lex->yacc_yyss)
+  {
+    my_free(lex->yacc_yyss, MYF(0));
+    my_free(lex->yacc_yyvs, MYF(0));
+    lex->yacc_yyss= 0;
+    lex->yacc_yyvs= 0;
+  }
+  DBUG_VOID_RETURN;
 }
 
 
@@ -1633,7 +1639,8 @@ void st_select_lex::print_limit(THD *thd, String *str)
 */
 
 st_lex::st_lex()
-  :result(0), sql_command(SQLCOM_END), query_tables_own_last(0)
+  :result(0), yacc_yyss(0), yacc_yyvs(0),
+   sql_command(SQLCOM_END), query_tables_own_last(0)
 {
   hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
   sroutines_list.empty();
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 47fbc685bab..f0bd85367d0 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -840,6 +840,7 @@ typedef struct st_lex
   udf_func udf;
   HA_CHECK_OPT   check_opt;			// check/repair options
   HA_CREATE_INFO create_info;
+  KEY_CREATE_INFO key_create_info;
   LEX_MASTER_INFO mi;				// used by CHANGE MASTER
   USER_RESOURCES mqh;
   ulong type;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d7808ab01da..8ee78578631 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -137,7 +137,7 @@ static void unlock_locked_tables(THD *thd)
 }
 
 
-static bool end_active_trans(THD *thd)
+bool end_active_trans(THD *thd)
 {
   int error=0;
   DBUG_ENTER("end_active_trans");
@@ -1008,6 +1008,7 @@ static int check_connection(THD *thd)
 
   char *user= end;
   char *passwd= strend(user)+1;
+  uint user_len= passwd - user - 1;
   char *db= passwd;
   char db_buff[NAME_LEN+1];                     // buffer to store db in utf8
   char user_buff[USERNAME_LENGTH+1];		// buffer to store user in utf8
@@ -1022,22 +1023,37 @@ static int check_connection(THD *thd)
     *passwd++ : strlen(passwd);
   db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
     db + passwd_len + 1 : 0;
+  uint db_len= db ? strlen(db) : 0;
+
+  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
+  {
+    inc_host_errors(&thd->remote.sin_addr);
+    return ER_HANDSHAKE_ERROR;
+  }
 
   /* Since 4.1 all database names are stored in utf8 */
   if (db)
   {
     db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
                              system_charset_info,
-                             db, strlen(db),
+                             db, db_len,
                              thd->charset(), &dummy_errors)]= 0;
     db= db_buff;
   }
 
-  user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1,
-                             system_charset_info, user, strlen(user),
-                             thd->charset(), &dummy_errors)]= '\0';
+  user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+                                       system_charset_info, user, user_len,
+                                       thd->charset(), &dummy_errors)]= '\0';
   user= user_buff;
 
+  /* If username starts and ends in "'", chop them off */
+  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
+  {
+    user[user_len-1]= 0;
+    user++;
+    user_len-= 2;
+  }
+
   if (thd->main_security_ctx.user)
     x_free(thd->main_security_ctx.user);
   if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
@@ -1606,7 +1622,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
   {
     char *db, *tbl_name;
     uint db_len= *(uchar*) packet;
+    if (db_len >= packet_length || db_len > NAME_LEN)
+    {
+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+      break;
+    }
     uint tbl_len= *(uchar*) (packet + db_len + 1);
+    if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN)
+    {
+      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+      break;
+    }
 
     statistic_increment(thd->status_var.com_other, &LOCK_status);
     thd->enable_slow_log= opt_log_slow_admin_statements;
@@ -1727,7 +1753,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
     if (alloc_query(thd, packet, packet_length))
       break;					// fatal error is set
     char *packet_end= thd->query + thd->query_length;
-    general_log_print(thd, command, "%s", thd->query);
+    general_log_print(thd, command, "%.*b", thd->query_length, thd->query);
     DBUG_PRINT("query",("%-.4096s",thd->query));
 
     if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -2935,8 +2961,7 @@ end_with_restore_list:
     thd->enable_slow_log= opt_log_slow_admin_statements;
     if (end_active_trans(thd))
       goto error;
-    else
-      res = mysql_create_index(thd, first_table, lex->key_list);
+    res= mysql_create_index(thd, first_table, lex->key_list);
     break;
 
 #ifdef HAVE_REPLICATION
@@ -3043,18 +3068,16 @@ end_with_restore_list:
       /* ALTER TABLE ends previous transaction */
       if (end_active_trans(thd))
 	goto error;
-      else
-      {
-        thd->enable_slow_log= opt_log_slow_admin_statements;
-	res= mysql_alter_table(thd, select_lex->db, lex->name,
-			       &lex->create_info,
-			       first_table, lex->create_list,
-			       lex->key_list,
-			       select_lex->order_list.elements,
-                               (ORDER *) select_lex->order_list.first,
-			       lex->duplicates, lex->ignore, &lex->alter_info,
-                               1);
-      }
+
+      thd->enable_slow_log= opt_log_slow_admin_statements;
+      res= mysql_alter_table(thd, select_lex->db, lex->name,
+                             &lex->create_info,
+                             first_table, lex->create_list,
+                             lex->key_list,
+                             select_lex->order_list.elements,
+                             (ORDER *) select_lex->order_list.first,
+                             lex->duplicates, lex->ignore, &lex->alter_info,
+                             1);
       break;
     }
 #endif /*DONT_ALLOW_SHOW_COMMANDS*/
@@ -3181,7 +3204,7 @@ end_with_restore_list:
 	check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
       goto error; /* purecov: inspected */
     thd->enable_slow_log= opt_log_slow_admin_statements;
-    res = mysql_analyze_table(thd, first_table, &lex->check_opt);
+    res= mysql_analyze_table(thd, first_table, &lex->check_opt);
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
@@ -3486,8 +3509,7 @@ end_with_restore_list:
       goto error;				/* purecov: inspected */
     if (end_active_trans(thd))
       goto error;
-    else
-      res = mysql_drop_index(thd, first_table, &lex->alter_info);
+    res= mysql_drop_index(thd, first_table, &lex->alter_info);
     break;
   case SQLCOM_SHOW_PROCESSLIST:
     if (!thd->security_ctx->priv_user[0] &&
@@ -5947,14 +5969,16 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
   if (type_modifier & PRI_KEY_FLAG)
   {
     lex->col_list.push_back(new key_part_spec(field_name,0));
-    lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF,
+    lex->key_list.push_back(new Key(Key::PRIMARY, NullS,
+                                    &default_key_create_info,
 				    0, lex->col_list));
     lex->col_list.empty();
   }
   if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
   {
     lex->col_list.push_back(new key_part_spec(field_name,0));
-    lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0,
+    lex->key_list.push_back(new Key(Key::UNIQUE, NullS,
+                                    &default_key_create_info, 0,
 				    lex->col_list));
     lex->col_list.empty();
   }
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0442ad724d2..71b8e9b1d95 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3430,6 +3430,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
 
   result= FALSE;
 end:
+  lex_end(thd->lex);
   thd->free_list= thd_free_list;
   thd->lex= old_lex;
   thd->variables.character_set_client= old_character_set_client;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index b4e42dc4700..01faae22c57 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -19,6 +19,8 @@
 #define REPORT_TO_LOG  1
 #define REPORT_TO_USER 2
 
+extern struct st_mysql_plugin *mysqld_builtins[];
+
 char *opt_plugin_dir_ptr;
 char opt_plugin_dir[FN_REFLEN];
 LEX_STRING plugin_type_names[]=
@@ -529,7 +531,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
   switch (plugin->plugin->type)
   {
   case MYSQL_STORAGE_ENGINE_PLUGIN:
-    if (ha_initialize_handlerton((handlerton*) plugin->plugin->info))
+    if (ha_initialize_handlerton(plugin))
     {
       sql_print_error("Plugin '%s' handlerton init returned error.",
                       plugin->name.str);
@@ -548,6 +550,53 @@ err:
   DBUG_RETURN(1);
 }
 
+static int plugin_finalize(THD *thd, struct st_plugin_int *plugin)
+{
+  int rc;
+  DBUG_ENTER("plugin_finalize");
+  
+  if (plugin->ref_count)
+  {
+    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+                 "Plugin is busy and will be uninstalled on shutdown");
+    goto err;
+  }
+  
+  switch (plugin->plugin->type)
+  {
+  case MYSQL_STORAGE_ENGINE_PLUGIN:
+    if (ha_finalize_handlerton(plugin))
+    {
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+                   "Storage engine shutdown failed. "
+                   "It will be uninstalled on shutdown");
+      sql_print_warning("Storage engine '%s' shutdown failed. "
+                        "It will be uninstalled on shutdown", plugin->name.str);
+      goto err;
+    }
+    break;
+  default:
+    break;
+  }
+
+  if (plugin->plugin->deinit)
+  {
+    if ((rc= plugin->plugin->deinit()))
+    {
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+                   "Plugin deinit failed. "
+                   "It will be uninstalled on shutdown");
+      sql_print_warning("Plugin '%s' deinit failed. "
+                        "It will be uninstalled on shutdown", plugin->name.str);
+      goto err;
+    }
+  }
+  
+  DBUG_RETURN(0);
+err:
+  DBUG_RETURN(1);
+}
+
 static void plugin_call_initializer(void)
 {
   uint i;
@@ -606,6 +655,8 @@ static byte *get_hash_key(const byte *buff, uint *length,
 int plugin_init(void)
 {
   int i;
+  struct st_mysql_plugin **builtins;
+  struct st_mysql_plugin *plugin;
   DBUG_ENTER("plugin_init");
 
   if (initialized)
@@ -625,6 +676,16 @@ int plugin_init(void)
                   get_hash_key, NULL, 0))
       goto err;
   }
+  
+  /* Register all the built-in plugins */
+  for (builtins= mysqld_builtins; *builtins; builtins++)
+  {
+    for (plugin= *builtins; plugin->info; plugin++)
+    {
+      if (plugin_register_builtin(plugin))
+        goto err;
+    }
+  }
 
   initialized= 1;
 
@@ -831,18 +892,10 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name)
     goto err;
   }
 
-  if (plugin->ref_count)
-  {
-    plugin->state= PLUGIN_IS_DELETED;
-    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
-                 "Plugin is not deleted, waiting on tables.");
-  }
-  else
-  {
-    if (plugin->plugin->deinit)
-      plugin->plugin->deinit();
+  if (!plugin_finalize(thd, plugin))
     plugin_del(name);
-  }
+  else
+    plugin->state= PLUGIN_IS_DELETED;
 
   table->field[0]->store(name->str, name->length, system_charset_info);
   table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index e0cf9095a22..6d0a0f4799c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1755,6 +1755,9 @@ static bool check_prepared_statement(Prepared_statement *stmt,
   case SQLCOM_CALL:
   case SQLCOM_CREATE_VIEW:
   case SQLCOM_DROP_VIEW:
+  case SQLCOM_REPAIR:
+  case SQLCOM_ANALYZE:
+  case SQLCOM_OPTIMIZE:
     break;
 
   default:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index aab126408f0..5f8c4dd2e1a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3360,33 +3360,46 @@ best_access_path(JOIN      *join,
     for (keyuse=s->keyuse ; keyuse->table == table ;)
     {
       key_part_map found_part= 0;
-      table_map found_ref=     0;
-      uint found_ref_or_null=  0;
-      uint key=     keyuse->key;
+      table_map found_ref= 0;
+      uint key= keyuse->key;
       KEY *keyinfo= table->key_info+key;
       bool ft_key=  (keyuse->keypart == FT_KEYPART);
+      uint found_ref_or_null= 0;
 
       /* Calculate how many key segments of the current key we can use */
       start_key= keyuse;
       do
       { /* for each keypart */
         uint keypart= keyuse->keypart;
-        uint found_part_ref_or_null= KEY_OPTIMIZE_REF_OR_NULL;
+        table_map best_part_found_ref= 0;
+        double best_prev_record_reads= DBL_MAX;
         do
         {
           if (!(remaining_tables & keyuse->used_tables) &&
               !(found_ref_or_null & keyuse->optimize))
           {
             found_part|= keyuse->keypart_map;
-            found_ref|=  keyuse->used_tables;
+            double tmp= prev_record_reads(join,
+					  (found_ref |
+					   keyuse->used_tables));
+            if (tmp < best_prev_record_reads)
+            {
+              best_part_found_ref= keyuse->used_tables;
+              best_prev_record_reads= tmp;
+            }
             if (rec > keyuse->ref_table_rows)
               rec= keyuse->ref_table_rows;
-            found_part_ref_or_null&= keyuse->optimize;
+	    /*
+	      If there is one 'key_column IS NULL' expression, we can
+	      use this ref_or_null optimisation of this field
+	    */
+	    found_ref_or_null|= (keyuse->optimize &
+				 KEY_OPTIMIZE_REF_OR_NULL);
           }
           keyuse++;
-          found_ref_or_null|= found_part_ref_or_null;
         } while (keyuse->table == table && keyuse->key == key &&
                  keyuse->keypart == keypart);
+	found_ref|= best_part_found_ref;
       } while (keyuse->table == table && keyuse->key == key);
 
       /*
@@ -3451,17 +3464,17 @@ best_access_path(JOIN      *join,
               }
             }
             /* Limit the number of matched rows */
-            tmp = records;
+            tmp= records;
             set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
             if (table->used_keys.is_set(key))
             {
               /* we can use only index tree */
               uint keys_per_block= table->file->block_size/2/
                 (keyinfo->key_length+table->file->ref_length)+1;
-              tmp = record_count*(tmp+keys_per_block-1)/keys_per_block;
+              tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
             }
             else
-              tmp = record_count*min(tmp,s->worst_seeks);
+              tmp= record_count*min(tmp,s->worst_seeks);
           }
         }
         else
@@ -3475,7 +3488,7 @@ best_access_path(JOIN      *join,
               (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
                found_part == PREV_BITS(uint,keyinfo->key_parts)))
           {
-            max_key_part=max_part_bit(found_part);
+            max_key_part= max_part_bit(found_part);
             /*
               Check if quick_range could determinate how many rows we
               will match
@@ -3486,8 +3499,8 @@ best_access_path(JOIN      *join,
             else
             {
               /* Check if we have statistic about the distribution */
-              if ((records = keyinfo->rec_per_key[max_key_part-1]))
-                tmp = records;
+              if ((records= keyinfo->rec_per_key[max_key_part-1]))
+                tmp= records;
               else
               {
                 /*
@@ -3548,13 +3561,13 @@ best_access_path(JOIN      *join,
               /* we can use only index tree */
               uint keys_per_block= table->file->block_size/2/
                 (keyinfo->key_length+table->file->ref_length)+1;
-              tmp = record_count*(tmp+keys_per_block-1)/keys_per_block;
+              tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
             }
             else
-              tmp = record_count*min(tmp,s->worst_seeks);
+              tmp= record_count*min(tmp,s->worst_seeks);
           }
           else
-            tmp = best_time;                    // Do nothing
+            tmp= best_time;                    // Do nothing
         }
       } /* not ft_key */
       if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
@@ -3906,7 +3919,8 @@ optimize_straight_join(JOIN *join, table_map join_tables)
   for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
   {
     /* Find the best access method from 's' to the current partial plan */
-    best_access_path(join, s, join->thd, join_tables, idx, record_count, read_time);
+    best_access_path(join, s, join->thd, join_tables, idx,
+                     record_count, read_time);
     /* compute the cost of the new plan extended with 's' */
     record_count*= join->positions[idx].records_read;
     read_time+=    join->positions[idx].read_time;
@@ -4029,8 +4043,9 @@ greedy_search(JOIN      *join,
         'join->best_positions' contains a complete optimal extension of the
         current partial QEP.
       */
-      DBUG_EXECUTE("opt", print_plan(join, read_time, record_count,
-                                     join->tables, "optimal"););
+      DBUG_EXECUTE("opt", print_plan(join, join->tables,
+                                     record_count, read_time, read_time,
+                                     "optimal"););
       DBUG_VOID_RETURN;
     }
 
@@ -4061,8 +4076,9 @@ greedy_search(JOIN      *join,
     --rem_size;
     ++idx;
 
-    DBUG_EXECUTE("opt",
-                 print_plan(join, read_time, record_count, idx, "extended"););
+    DBUG_EXECUTE("opt", print_plan(join, join->tables,
+                                   record_count, read_time, read_time,
+                                   "extended"););
   } while (TRUE);
 }
 
@@ -4085,13 +4101,14 @@ greedy_search(JOIN      *join,
     read_time        the cost of the best partial plan
     search_depth     maximum depth of the recursion and thus size of the found
                      optimal plan (0 < search_depth <= join->tables+1).
-    prune_level      pruning heuristics that should be applied during optimization
+    prune_level      pruning heuristics that should be applied during
+                     optimization
                      (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)
 
   DESCRIPTION
     The procedure searches for the optimal ordering of the query tables in set
-    'remaining_tables' of size N, and the corresponding optimal access paths to each
-    table. The choice of a table order and an access path for each table
+    'remaining_tables' of size N, and the corresponding optimal access paths to
+    each table. The choice of a table order and an access path for each table
     constitutes a query execution plan (QEP) that fully specifies how to
     execute the query.
    
@@ -4201,8 +4218,8 @@ best_extension_by_limited_search(JOIN      *join,
   double best_record_count= DBL_MAX;
   double best_read_time=    DBL_MAX;
 
-  DBUG_EXECUTE("opt",
-               print_plan(join, read_time, record_count, idx, "part_plan"););
+  DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
+                                "part_plan"););
 
   for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
   {
@@ -4214,7 +4231,8 @@ best_extension_by_limited_search(JOIN      *join,
       double current_record_count, current_read_time;
 
       /* Find the best access method from 's' to the current partial plan */
-      best_access_path(join, s, thd, remaining_tables, idx, record_count, read_time);
+      best_access_path(join, s, thd, remaining_tables, idx,
+                       record_count, read_time);
       /* Compute the cost of extending the plan with 's' */
       current_record_count= record_count * join->positions[idx].records_read;
       current_read_time=    read_time + join->positions[idx].read_time;
@@ -4223,7 +4241,12 @@ best_extension_by_limited_search(JOIN      *join,
       if ((current_read_time +
            current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
       {
-        DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
+        DBUG_EXECUTE("opt", print_plan(join, idx+1,
+                                       current_record_count,
+                                       read_time,
+                                       (current_read_time +
+                                        current_record_count / 
+                                        (double) TIME_FOR_COMPARE),
                                        "prune_by_cost"););
         restore_prev_nj_state(s);
         continue;
@@ -4252,7 +4275,10 @@ best_extension_by_limited_search(JOIN      *join,
         }
         else
         {
-          DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
+          DBUG_EXECUTE("opt", print_plan(join, idx+1,
+                                         current_record_count,
+                                         read_time,
+                                         current_read_time,
                                          "pruned_by_heuristic"););
           restore_prev_nj_state(s);
           continue;
@@ -4280,7 +4306,8 @@ best_extension_by_limited_search(JOIN      *join,
         */
         current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
         if (join->sort_by_table &&
-            join->sort_by_table != join->positions[join->const_tables].table->table)
+            join->sort_by_table !=
+            join->positions[join->const_tables].table->table)
           /* We have to make a temp table */
           current_read_time+= current_record_count;
         if ((search_depth == 1) || (current_read_time < join->best_read))
@@ -4289,8 +4316,10 @@ best_extension_by_limited_search(JOIN      *join,
                  sizeof(POSITION) * (idx + 1));
           join->best_read= current_read_time - 0.001;
         }
-        DBUG_EXECUTE("opt", print_plan(join, current_read_time, 
-                                       current_record_count, idx, 
+        DBUG_EXECUTE("opt", print_plan(join, idx+1,
+                                       current_record_count,
+                                       read_time,
+                                       current_read_time,
                                        "full_plan"););
       }
       restore_prev_nj_state(s);
@@ -4311,7 +4340,6 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
   ha_rows rec;
   double tmp;
   THD *thd= join->thd;
-
   if (!rest_tables)
   {
     DBUG_PRINT("best",("read_time: %g  record_count: %g",read_time,
@@ -12690,6 +12718,10 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
       if (item->type() != Item::SUM_FUNC_ITEM && !item->marker &&
 	  !item->const_item())
       {
+        /*
+          TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
+          ER_NON_GROUPING_FIELD_USED
+        */
 	my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name());
 	return 1;
       }
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 95433828a1e..4071f86989f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -42,6 +42,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
                                grant_names, NULL};
 #endif
 
+static void store_key_options(THD *thd, String *packet, TABLE *table,
+                              KEY *key_info);
+
 /***************************************************************************
 ** List all table types supported 
 ***************************************************************************/
@@ -119,7 +122,7 @@ static my_bool show_plugins(THD *thd, st_plugin_int *plugin,
         make_version_string(version_buf, sizeof(version_buf), plug->version),
         cs);
 
-    
+
   switch (plugin->state)
   {
   /* case PLUGIN_IS_FREED: does not happen */
@@ -929,15 +932,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
   handler *file= table->file;
   TABLE_SHARE *share= table->s;
   HA_CREATE_INFO create_info;
-  my_bool foreign_db_mode=    (thd->variables.sql_mode & (MODE_POSTGRESQL |
-							  MODE_ORACLE |
-							  MODE_MSSQL |
-							  MODE_DB2 |
-							  MODE_MAXDB |
-							  MODE_ANSI)) != 0;
-  my_bool limited_mysql_mode= (thd->variables.sql_mode &
-			       (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
-				MODE_MYSQL40)) != 0;
+  bool foreign_db_mode=  (thd->variables.sql_mode & (MODE_POSTGRESQL |
+                                                     MODE_ORACLE |
+                                                     MODE_MSSQL |
+                                                     MODE_DB2 |
+                                                     MODE_MAXDB |
+                                                     MODE_ANSI)) != 0;
   DBUG_ENTER("store_create_info");
   DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
 
@@ -1100,22 +1100,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
     if (!found_primary)
      append_identifier(thd, packet, key_info->name, strlen(key_info->name));
 
-    if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
-	!limited_mysql_mode && !foreign_db_mode)
-    {
-      if (key_info->algorithm == HA_KEY_ALG_BTREE)
-        packet->append(STRING_WITH_LEN(" USING BTREE"));
+#if MYSQL_VERSION_ID < 50300
+    /* Key options moved to after key parts in 5.3.0 */
+    if (!thd->variables.new_mode)
+      store_key_options(thd, packet, table, key_info);
+#endif
 
-      if (key_info->algorithm == HA_KEY_ALG_HASH)
-        packet->append(STRING_WITH_LEN(" USING HASH"));
-
-      // +BAR: send USING only in non-default case: non-spatial rtree
-      if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
-	  !(key_info->flags & HA_SPATIAL))
-        packet->append(STRING_WITH_LEN(" USING RTREE"));
-
-      // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
-    }
     packet->append(STRING_WITH_LEN(" ("));
 
     for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
@@ -1140,6 +1130,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
       }
     }
     packet->append(')');
+#if MYSQL_VERSION_ID < 50300
+    if (thd->variables.new_mode)
+#endif
+      store_key_options(thd, packet, table, key_info);
     if (key_info->parser)
     {
       packet->append(" WITH PARSER ", 13);
@@ -1252,6 +1246,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
       packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
       packet->append(ha_row_type[(uint) share->row_type]);
     }
+    if (table->s->key_block_size)
+    {
+      packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
+      end= longlong10_to_str(table->s->key_block_size, buff, 10);
+      packet->append(buff, (uint) (end - buff));
+    }
     table->file->append_create_info(packet);
     if (share->comment && share->comment[0])
     {
@@ -1286,6 +1286,47 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
   DBUG_RETURN(0);
 }
 
+
+static void store_key_options(THD *thd, String *packet, TABLE *table,
+                              KEY *key_info)
+{
+  bool limited_mysql_mode= (thd->variables.sql_mode &
+                            (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
+                             MODE_MYSQL40)) != 0;
+  bool foreign_db_mode=  (thd->variables.sql_mode & (MODE_POSTGRESQL |
+                                                     MODE_ORACLE |
+                                                     MODE_MSSQL |
+                                                     MODE_DB2 |
+                                                     MODE_MAXDB |
+                                                     MODE_ANSI)) != 0;
+  char *end, buff[32];
+
+  if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
+      !limited_mysql_mode && !foreign_db_mode)
+  {
+
+    if (key_info->algorithm == HA_KEY_ALG_BTREE)
+      packet->append(STRING_WITH_LEN(" USING BTREE"));
+
+    if (key_info->algorithm == HA_KEY_ALG_HASH)
+      packet->append(STRING_WITH_LEN(" USING HASH"));
+
+    /* send USING only in non-default case: non-spatial rtree */
+    if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
+        !(key_info->flags & HA_SPATIAL))
+      packet->append(STRING_WITH_LEN(" USING RTREE"));
+
+    if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
+        table->s->key_block_size != key_info->block_size)
+    {
+      packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
+      end= longlong10_to_str(key_info->block_size, buff, 10);
+      packet->append(buff, (uint) (end - buff));
+    }
+  }
+}
+
+
 void
 view_store_options(THD *thd, TABLE_LIST *table, String *buff)
 {
@@ -1553,15 +1594,11 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
   TABLE *table= tables->table;
   CHARSET_INFO *cs= system_charset_info;
   char *user;
-  bool verbose;
-  ulong max_query_length;
   time_t now= time(0);
   DBUG_ENTER("fill_process_list");
 
   user= thd->security_ctx->master_access & PROCESS_ACL ?
         NullS : thd->security_ctx->priv_user;
-  verbose= thd->lex->verbose;
-  max_query_length= PROCESS_LIST_WIDTH;
 
   VOID(pthread_mutex_lock(&LOCK_thread_count));
 
@@ -1645,7 +1682,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
       if (tmp->query)
       {
         table->field[7]->store(tmp->query,
-                               min(max_query_length, tmp->query_length), cs);
+                               min(PROCESS_LIST_INFO_WIDTH,
+                                   tmp->query_length), cs);
         table->field[7]->set_notnull();
       }
 
@@ -3000,46 +3038,49 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
 }
 
 
-int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
+static my_bool iter_schema_engines(THD *thd, st_plugin_int *plugin,
+                                   void *ptable)
 {
+  TABLE *table= (TABLE *) ptable;
+  handlerton *hton= (handlerton *) plugin->plugin->info;
   const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-  TABLE *table= tables->table;
   CHARSET_INFO *scs= system_charset_info;
-  handlerton **types;
+  DBUG_ENTER("iter_schema_engines");
 
-  DBUG_ENTER("fill_schema_engines");
-
-  for (types= sys_table_types; *types; types++)
+  if (!(hton->flags & HTON_HIDDEN))
   {
-    if ((*types)->flags & HTON_HIDDEN)
-      continue;
-
     if (!(wild && wild[0] &&
-          wild_case_compare(scs, (*types)->name,wild)))
+          wild_case_compare(scs, hton->name,wild)))
     {
       const char *tmp;
       restore_record(table, s->default_values);
 
-      table->field[0]->store((*types)->name, strlen((*types)->name), scs);
-      tmp= (*types)->state ? "DISABLED" : "ENABLED";
+      table->field[0]->store(hton->name, strlen(hton->name), scs);
+      tmp= hton->state ? "DISABLED" : "ENABLED";
       table->field[1]->store( tmp, strlen(tmp), scs);
-      table->field[2]->store((*types)->comment, strlen((*types)->comment), scs);
-      tmp= (*types)->commit ? "YES" : "NO";
+      table->field[2]->store(hton->comment, strlen(hton->comment), scs);
+      tmp= hton->commit ? "YES" : "NO";
       table->field[3]->store( tmp, strlen(tmp), scs);
-      tmp= (*types)->prepare ? "YES" : "NO";
+      tmp= hton->prepare ? "YES" : "NO";
       table->field[4]->store( tmp, strlen(tmp), scs);
-      tmp= (*types)->savepoint_set ? "YES" : "NO";
+      tmp= hton->savepoint_set ? "YES" : "NO";
       table->field[5]->store( tmp, strlen(tmp), scs);
 
       if (schema_table_store_record(thd, table))
         DBUG_RETURN(1);
     }
   }
-
   DBUG_RETURN(0);
 }
 
 
+int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+  return plugin_foreach(thd, iter_schema_engines, 
+                        MYSQL_STORAGE_ENGINE_PLUGIN, tables->table);
+}
+
+
 int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
 {
   CHARSET_INFO **cs;
@@ -4231,6 +4272,75 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
 }
 
 
+/*
+  Fill and store records into I_S.referential_constraints table
+
+  SYNOPSIS
+    get_referential_constraints_record()
+    thd                 thread handle
+    tables              table list struct(processed table)
+    table               I_S table
+    res                 1 means the error during opening of the processed table
+                        0 means processed table is opened without error
+    base_name           db name
+    file_name           table name
+
+  RETURN
+    0	ok
+    #   error
+*/
+
+static int
+get_referential_constraints_record(THD *thd, struct st_table_list *tables,
+                                   TABLE *table, bool res,
+                                   const char *base_name, const char *file_name)
+{
+  CHARSET_INFO *cs= system_charset_info;
+  DBUG_ENTER("get_referential_constraints_record");
+
+  if (res)
+  {
+    if (!tables->view)
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                   thd->net.last_errno, thd->net.last_error);
+    thd->clear_error();
+    DBUG_RETURN(0);
+  }
+  if (!tables->view)
+  {
+    List f_key_list;
+    TABLE *show_table= tables->table;
+    show_table->file->info(HA_STATUS_VARIABLE | 
+                           HA_STATUS_NO_LOCK |
+                           HA_STATUS_TIME);
+
+    show_table->file->get_foreign_key_list(thd, &f_key_list);
+    FOREIGN_KEY_INFO *f_key_info;
+    List_iterator_fast it(f_key_list);
+    while ((f_key_info= it++))
+    {
+      restore_record(table, s->default_values);
+      table->field[1]->store(base_name, strlen(base_name), cs);
+      table->field[9]->store(file_name, strlen(file_name), cs);
+      table->field[2]->store(f_key_info->forein_id->str,
+                             f_key_info->forein_id->length, cs);
+      table->field[4]->store(f_key_info->referenced_db->str, 
+                             f_key_info->referenced_db->length, cs);
+      table->field[5]->store(f_key_info->referenced_table->str, 
+                             f_key_info->referenced_table->length, cs);
+      table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
+      table->field[7]->store(f_key_info->update_method->str, 
+                             f_key_info->update_method->length, cs);
+      table->field[8]->store(f_key_info->delete_method->str, 
+                             f_key_info->delete_method->length, cs);
+      if (schema_table_store_record(thd, table))
+        DBUG_RETURN(1);
+    }
+  }
+  DBUG_RETURN(0);
+}
+
+
 /*
   Find schema_tables elment by name
 
@@ -5096,9 +5206,9 @@ ST_FIELD_INFO processlist_fields_info[]=
   {"HOST", LIST_PROCESS_HOST_LEN,  MYSQL_TYPE_STRING, 0, 0, "Host"},
   {"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
   {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
-  {"TIME", 4, MYSQL_TYPE_LONG, 0, 0, "Time"},
+  {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time"},
   {"STATE", 30, MYSQL_TYPE_STRING, 0, 1, "State"},
-  {"INFO", PROCESS_LIST_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
+  {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
@@ -5160,6 +5270,22 @@ ST_FIELD_INFO files_fields_info[]=
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
+ST_FIELD_INFO referential_constraints_fields_info[]=
+{
+  {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
 /*
   Description of ST_FIELD_INFO in table.h
 
@@ -5195,6 +5321,9 @@ ST_SCHEMA_TABLE schema_tables[]=
     fill_plugins, make_old_format, 0, -1, -1, 0},
   {"PROCESSLIST", processlist_fields_info, create_schema_table,
     fill_schema_processlist, make_old_format, 0, -1, -1, 0},
+  {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
+   create_schema_table, get_all_tables, 0, get_referential_constraints_record,
+   1, 9, 0},
   {"ROUTINES", proc_fields_info, create_schema_table, 
     fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
   {"SCHEMATA", schema_fields_info, create_schema_table,
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 79228be8a76..19ee9f259dc 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -331,7 +331,7 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
   return copy_aligned(str, arg_length, offset, cs);
 }
 
-	/* Copy with charset convertion */
+	/* Copy with charset conversion */
 
 bool String::copy(const char *str, uint32 arg_length,
 		  CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index f71234a6087..f890f504952 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -231,10 +231,9 @@ static int mysql_copy_key_list(List *orig_key,
       }
     }
     if (!(temp_key= new Key(prep_key->type, prep_key->name,
-                            prep_key->algorithm,
+                            &prep_key->key_create_info,
                             prep_key->generated,
-                            prep_columns,
-                            prep_key->parser_name)))
+                            prep_columns)))
     {
       mem_alloc_error(sizeof(Key));
       DBUG_RETURN(TRUE);
@@ -428,10 +427,6 @@ static uint read_ddl_log_header()
   bool successful_open= FALSE;
   DBUG_ENTER("read_ddl_log_header");
 
-  bzero(file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
-  global_ddl_log.inited= FALSE;
-  global_ddl_log.recovery_phase= TRUE;
-  global_ddl_log.io_size= IO_SIZE;
   create_ddl_log_file_name(file_name);
   if ((global_ddl_log.file_id= my_open(file_name,
                                         O_RDWR | O_BINARY, MYF(MY_WME))) >= 0)
@@ -508,12 +503,14 @@ bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
   Initialise ddl log
   SYNOPSIS
     init_ddl_log()
-  RETURN VALUES
-    TRUE                     Error
-    FALSE                    Success
+
   DESCRIPTION
     Write the header of the ddl log file and length of names. Also set
     number of entries to zero.
+
+  RETURN VALUES
+    TRUE                     Error
+    FALSE                    Success
 */
 
 static bool init_ddl_log()
@@ -523,9 +520,8 @@ static bool init_ddl_log()
   DBUG_ENTER("init_ddl_log");
 
   if (global_ddl_log.inited)
-  {
-    DBUG_RETURN(FALSE);
-  }
+    goto end;
+
   global_ddl_log.io_size= IO_SIZE;
   create_ddl_log_file_name(file_name);
   if ((global_ddl_log.file_id= my_create(file_name,
@@ -540,9 +536,12 @@ static bool init_ddl_log()
   global_ddl_log.inited= TRUE;
   if (write_ddl_log_header())
   {
+    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
     global_ddl_log.inited= FALSE;
     DBUG_RETURN(TRUE);
   }
+
+end:
   DBUG_RETURN(FALSE);
 }
 
@@ -1067,6 +1066,15 @@ void execute_ddl_log_recovery()
   char file_name[FN_REFLEN];
   DBUG_ENTER("execute_ddl_log_recovery");
 
+  /*
+    Initialise global_ddl_log struct
+  */
+  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
+  global_ddl_log.inited= FALSE;
+  global_ddl_log.recovery_phase= TRUE;
+  global_ddl_log.io_size= IO_SIZE;
+  global_ddl_log.file_id= (File) -1;
+
   /*
     To be able to run this from boot, we allocate a temporary THD
   */
@@ -1130,7 +1138,12 @@ void release_ddl_log()
     my_free((char*)free_list, MYF(0));
     free_list= tmp;
   }
-  VOID(my_close(global_ddl_log.file_id, MYF(0)));
+  if (global_ddl_log.file_id >= 0)
+  {
+    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
+    global_ddl_log.file_id= (File) -1;
+  }
+  global_ddl_log.inited= 0;
   pthread_mutex_unlock(&LOCK_gdl);
   VOID(pthread_mutex_destroy(&LOCK_gdl));
   DBUG_VOID_RETURN;
@@ -2184,7 +2197,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
         if (need_to_change_arena)
           thd->restore_active_arena(thd->stmt_arena, &backup_arena);
 
-        if (! sql_field->def)
+        if (sql_field->def == NULL)
         {
           /* Could not convert */
           my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
@@ -2195,15 +2208,30 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
       if (sql_field->sql_type == FIELD_TYPE_SET)
       {
         uint32 field_length;
-        if (sql_field->def)
+        if (sql_field->def != NULL)
         {
           char *not_used;
           uint not_used2;
           bool not_found= 0;
           String str, *def= sql_field->def->val_str(&str);
-          def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
-          (void) find_set(interval, def->ptr(), def->length(),
-                          cs, ¬_used, ¬_used2, ¬_found);
+          if (def == NULL) /* SQL "NULL" maps to NULL */
+          {
+            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
+            {
+              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+              DBUG_RETURN(-1);
+            }
+
+            /* else, NULL is an allowed value */
+            (void) find_set(interval, NULL, 0,
+                            cs, ¬_used, ¬_used2, ¬_found);
+          }
+          else /* not NULL */
+          {
+            (void) find_set(interval, def->ptr(), def->length(),
+                            cs, ¬_used, ¬_used2, ¬_found);
+          }
+
           if (not_found)
           {
             my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
@@ -2216,14 +2244,28 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
       else  /* FIELD_TYPE_ENUM */
       {
         uint32 field_length;
-        if (sql_field->def)
+        DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM);
+        if (sql_field->def != NULL)
         {
           String str, *def= sql_field->def->val_str(&str);
-          def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
-          if (!find_type2(interval, def->ptr(), def->length(), cs))
+          if (def == NULL) /* SQL "NULL" maps to NULL */
           {
-            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-            DBUG_RETURN(-1);
+            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
+            {
+              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+              DBUG_RETURN(-1);
+            }
+
+            /* else, the defaults yield the correct length for NULLs. */
+          } 
+          else /* not NULL */
+          {
+            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
+            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
+            {
+              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+              DBUG_RETURN(-1);
+            }
           }
         }
         calculate_interval_lengths(cs, interval, &field_length, &dummy);
@@ -2466,14 +2508,16 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
 	break;
     }
 
-    switch(key->type){
+    switch (key->type) {
     case Key::MULTIPLE:
 	key_info->flags= 0;
 	break;
     case Key::FULLTEXT:
 	key_info->flags= HA_FULLTEXT;
-	if ((key_info->parser_name= key->parser_name))
+	if ((key_info->parser_name= &key->key_create_info.parser_name)->str)
           key_info->flags|= HA_USES_PARSER;
+        else
+          key_info->parser_name= 0;
 	break;
     case Key::SPATIAL:
 #ifdef HAVE_SPATIAL
@@ -2497,7 +2541,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
     key_info->key_parts=(uint8) key->columns.elements;
     key_info->key_part=key_part_info;
     key_info->usable_key_parts= key_number;
-    key_info->algorithm=key->algorithm;
+    key_info->algorithm= key->key_create_info.algorithm;
 
     if (key->type == Key::FULLTEXT)
     {
@@ -2519,6 +2563,12 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
     /* TODO: Add proper checks if handler supports key_type and algorithm */
     if (key_info->flags & HA_SPATIAL)
     {
+      if (!(file->table_flags() & HA_CAN_RTREEKEYS))
+      {
+        my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
+                   MYF(0));
+        DBUG_RETURN(-1);
+      }
       if (key_info->key_parts != 1)
       {
 	my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
@@ -2543,6 +2593,18 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
 #endif
     }
 
+    /* Take block size from key part or table part */
+    /*
+      TODO: Add warning if block size changes. We can't do it here, as
+      this may depend on the size of the key
+    */
+    key_info->block_size= (key->key_create_info.block_size ?
+                           key->key_create_info.block_size :
+                           create_info->key_block_size);
+
+    if (key_info->block_size)
+      key_info->flags|= HA_USES_BLOCK_SIZE;
+
     List_iterator cols(key->columns), cols2(key->columns);
     CHARSET_INFO *ft_key_charset=0;  // for FULLTEXT
     for (uint column_nr=0 ; (column=cols++) ; column_nr++)
@@ -3516,7 +3578,9 @@ mysql_rename_table(handlerton *base,
     }
   }
   delete file;
-  if (error)
+  if (error == HA_ERR_WRONG_COMMAND)
+    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
+  else if (error)
     my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
   DBUG_RETURN(error != 0);
 }
@@ -3834,6 +3898,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
   int result_code;
   DBUG_ENTER("mysql_admin_table");
 
+  if (end_active_trans(thd))
+    DBUG_RETURN(1);
   field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
   item->maybe_null = 1;
   field_list.push_back(item = new Item_empty_string("Op", 10));
@@ -3884,6 +3950,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
     {
       switch ((*prepare_func)(thd, table, check_opt)) {
       case  1:           // error, message written to net
+        ha_autocommit_or_rollback(thd, 1);
         close_thread_tables(thd);
         continue;
       case -1:           // error, message could be written to net
@@ -3925,6 +3992,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
         View opening can be interrupted in the middle of process so some
         tables can be left opening
       */
+      ha_autocommit_or_rollback(thd, 1);
       close_thread_tables(thd);
       if (protocol->write())
 	goto err;
@@ -3949,6 +4017,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
       length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
                           table_name);
       protocol->store(buff, length, system_charset_info);
+      ha_autocommit_or_rollback(thd, 0);
       close_thread_tables(thd);
       table->table=0;				// For query cache
       if (protocol->write())
@@ -3994,6 +4063,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
           (table->table->file->ha_check_for_upgrade(check_opt) ==
            HA_ADMIN_NEEDS_ALTER))
       {
+        ha_autocommit_or_rollback(thd, 1);
         close_thread_tables(thd);
         tmp_disable_binlog(thd); // binlogging is done by caller if wanted
         result_code= mysql_recreate_table(thd, table, 0);
@@ -4080,6 +4150,7 @@ send_result_message:
         "try with alter", so here we close the table, do an ALTER TABLE,
         reopen the table and do ha_innobase::analyze() on it.
       */
+      ha_autocommit_or_rollback(thd, 0);
       close_thread_tables(thd);
       TABLE_LIST *save_next_local= table->next_local,
                  *save_next_global= table->next_global;
@@ -4087,6 +4158,7 @@ send_result_message:
       tmp_disable_binlog(thd); // binlogging is done by caller if wanted
       result_code= mysql_recreate_table(thd, table, 0);
       reenable_binlog(thd);
+      ha_autocommit_or_rollback(thd, 0);
       close_thread_tables(thd);
       if (!result_code) // recreation went ok
       {
@@ -4161,14 +4233,20 @@ send_result_message:
         table->table->s->version=0;               // Force close of table
       else if (open_for_modify && !table->table->s->log_table)
       {
-        pthread_mutex_lock(&LOCK_open);
-        remove_table_from_cache(thd, table->table->s->db.str,
-                                table->table->s->table_name.str, RTFC_NO_FLAG);
-        pthread_mutex_unlock(&LOCK_open);
-        /* Something may be modified, that's why we have to invalidate cache */
+        if (table->table->s->tmp_table)
+          table->table->file->info(HA_STATUS_CONST);
+        else
+        {
+          pthread_mutex_lock(&LOCK_open);
+          remove_table_from_cache(thd, table->table->s->db.str,
+                                  table->table->s->table_name.str, RTFC_NO_FLAG);
+          pthread_mutex_unlock(&LOCK_open);
+        }
+        /* May be something modified consequently we have to invalidate cache */
         query_cache_invalidate3(thd, table->table, 0);
       }
     }
+    ha_autocommit_or_rollback(thd, 0);
     close_thread_tables(thd);
     table->table=0;				// For query cache
     if (protocol->write())
@@ -4177,7 +4255,9 @@ send_result_message:
 
   send_eof(thd);
   DBUG_RETURN(FALSE);
+
  err:
+  ha_autocommit_or_rollback(thd, 1);
   close_thread_tables(thd);			// Shouldn't be needed
   if (table)
     table->table=0;
@@ -4632,7 +4712,9 @@ mysql_discard_or_import_tablespace(THD *thd,
   if (error)
     goto err;
   write_bin_log(thd, FALSE, thd->query, thd->query_length);
+
 err:
+  ha_autocommit_or_rollback(thd, error);
   close_thread_tables(thd);
   thd->tablespace_op=FALSE;
   
@@ -5113,6 +5195,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
     create_info->avg_row_length= table->s->avg_row_length;
   if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
     create_info->default_table_charset= table->s->table_charset;
+  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
+    create_info->key_block_size= table->s->key_block_size;
 
   restore_record(table, s->default_values);     // Empty record for DEFAULT
   List_iterator drop_it(alter_info->drop_list);
@@ -5315,6 +5399,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 					    key_part_length));
     }
     if (key_parts.elements)
+    {
+      KEY_CREATE_INFO key_create_info;
+      bzero((char*) &key_create_info, sizeof(key_create_info));
+
+      key_create_info.algorithm= key_info->algorithm;
+      if (key_info->flags & HA_USES_BLOCK_SIZE)
+        key_create_info.block_size= key_info->block_size;
+      if (key_info->flags & HA_USES_PARSER)
+        key_create_info.parser_name= *key_info->parser_name;
+
       key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
 				 (key_info->flags & HA_NOSAME ?
 				 (!my_strcasecmp(system_charset_info,
@@ -5323,11 +5417,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 				  (key_info->flags & HA_FULLTEXT ?
 				   Key::FULLTEXT : Key::MULTIPLE)),
 				 key_name,
-				 key_info->algorithm,
+                                 &key_create_info,
                                  test(key_info->flags & HA_GENERATED_KEY),
-				 key_parts,
-                                 key_info->flags & HA_USES_PARSER ?
-                                 &key_info->parser->name : 0));
+				 key_parts));
+    }
   }
   {
     Key *key;
@@ -5423,9 +5516,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
       while ((prep_col= prep_col_it++))
         prep_columns.push_back(new key_part_spec(*prep_col));
       prepared_key_list.push_back(new Key(prep_key->type, prep_key->name,
-                                          prep_key->algorithm,
-                                          prep_key->generated, prep_columns,
-                                          prep_key->parser_name));
+                                          &prep_key->key_create_info,
+                                          prep_key->generated, prep_columns));
     }
 
     /* Create the prepared information. */
@@ -6309,7 +6401,8 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
 }
 
 
-bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
+bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
+                          HA_CHECK_OPT *check_opt)
 {
   TABLE_LIST *table;
   List field_list;
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index bf86630d28c..b28aa4a1ce5 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -230,8 +230,8 @@ TEST_join(JOIN *join)
 */
 
 void
-print_plan(JOIN* join, double read_time, double record_count,
-           uint idx, const char *info)
+print_plan(JOIN* join, uint idx, double record_count, double read_time,
+           double current_read_time, const char *info)
 {
   uint i;
   POSITION pos;
@@ -245,13 +245,15 @@ print_plan(JOIN* join, double read_time, double record_count,
   DBUG_LOCK_FILE;
   if (join->best_read == DBL_MAX)
   {
-    fprintf(DBUG_FILE,"%s; idx:%u, best: DBL_MAX, current:%g\n",
-            info, idx, read_time);
+    fprintf(DBUG_FILE,
+    "%s; idx:%u, best: DBL_MAX, atime: %g, itime: %g, count: %g\n",
+    info, idx, current_read_time, read_time, record_count);
   }
   else
   {
-    fprintf(DBUG_FILE,"%s; idx: %u, best: %g, current: %g\n",
-            info, idx, join->best_read, read_time);
+    fprintf(DBUG_FILE,
+    "%s; idx:%u, best: %g, accumulated: %g, increment: %g, count: %g\n",
+    info, idx, join->best_read, current_read_time, read_time, record_count);
   }
 
   /* Print the tables in JOIN->positions */
@@ -270,9 +272,9 @@ print_plan(JOIN* join, double read_time, double record_count,
     Print the tables in JOIN->best_positions only if at least one complete plan
     has been found. An indicator for this is the value of 'join->best_read'.
   */
-  fputs("BEST_POSITIONS: ", DBUG_FILE);
   if (join->best_read < DBL_MAX)
   {
+    fputs("BEST_POSITIONS: ", DBUG_FILE);
     for (i= 0; i < idx ; i++)
     {
       pos= join->best_positions[i];
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3ef6a234f4e..8e5a776950d 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -943,7 +943,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
         goto err;
     }
 
-
     if (!(table->view_tables=
           (List*) new(thd->mem_root) List))
       goto err;
@@ -1194,6 +1193,7 @@ ok2:
     old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used;
   result= !table->prelocking_placeholder && table->prepare_security(thd);
 
+  lex_end(thd->lex);
 end:
   if (arena)
     thd->restore_active_arena(arena, &backup);
@@ -1201,6 +1201,8 @@ end:
   DBUG_RETURN(result);
 
 err:
+  DBUG_ASSERT(thd->lex == table->view);
+  lex_end(thd->lex);
   delete table->view;
   table->view= 0;	// now it is not VIEW placeholder
   result= 1;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ab87c78d17c..32b5bc8adb9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -364,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 %token  JOIN_SYM
 %token  KEYS
 %token  KEY_SYM
+%token  KEY_BLOCK_SIZE
 %token  KILL_SYM
 %token  LANGUAGE_SYM
 %token  LAST_INSERT_ID
@@ -730,7 +731,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
         sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem
 
 %type 
-	opt_table_alias opt_fulltext_parser
+	opt_table_alias
 
 %type 
 	table_ident table_ident_nodb references xid
@@ -795,7 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 	key_type opt_unique_or_fulltext constraint_key_type
 
 %type 
-	key_alg opt_btree_or_rtree
+	opt_btree_or_rtree
 
 %type 
 	key_usage_list using_list
@@ -886,6 +887,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
         view_suid view_tail view_list_opt view_list view_select
         view_check_option trigger_tail sp_tail
         install uninstall partition_entry binlog_base64_event
+	init_key_options key_options key_opts key_opt
 END_OF_INPUT
 
 %type  call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1220,11 +1222,13 @@ create:
 	}
 	create2
 	  { Lex->current_select= &Lex->select_lex; }
-	| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident
+	| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON
+	  table_ident
 	  {
 	    LEX *lex=Lex;
 	    lex->sql_command= SQLCOM_CREATE_INDEX;
-	    if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
+	    if (!lex->current_select->add_table_to_list(lex->thd, $7,
+							NULL,
 							TL_OPTION_UPDATING))
 	      YYABORT;
 	    lex->create_list.empty();
@@ -1232,15 +1236,16 @@ create:
 	    lex->col_list.empty();
 	    lex->change=NullS;
 	  }
-	   '(' key_list ')' opt_fulltext_parser
+	   '(' key_list ')' key_options
 	  {
 	    LEX *lex=Lex;
-	    if ($2 != Key::FULLTEXT && $12)
+	    if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
 	    {
 	      yyerror(ER(ER_SYNTAX_ERROR));
 	      YYABORT;
 	    }
-	    lex->key_list.push_back(new Key($2,$4.str,$5,0,lex->col_list,$12));
+	    lex->key_list.push_back(new Key($2, $4.str, &lex->key_create_info, 0,
+					   lex->col_list));
 	    lex->col_list.empty();
 	  }
 	| CREATE DATABASE opt_if_not_exists ident
@@ -3890,6 +3895,11 @@ create_table_option:
         | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;}
         | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;}
 	| CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length;  Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; }
+	| KEY_BLOCK_SIZE opt_equal ulong_num
+	  {
+	    Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
+	    Lex->create_info.key_block_size= $3;
+	  }
         ;
 
 default_charset:
@@ -3983,23 +3993,25 @@ column_def:
 	;
 
 key_def:
-	key_type opt_ident key_alg '(' key_list ')' opt_fulltext_parser
+	key_type opt_ident key_alg '(' key_list ')' key_options
 	  {
 	    LEX *lex=Lex;
-	    if ($1 != Key::FULLTEXT && $7)
+	    if ($1 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
 	    {
 	      yyerror(ER(ER_SYNTAX_ERROR));
 	      YYABORT;
 	    }
-	    lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list, $7));
+	    lex->key_list.push_back(new Key($1,$2, &lex->key_create_info, 0,
+					   lex->col_list));
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
-	| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
+	| opt_constraint constraint_key_type opt_ident key_alg
+	  '(' key_list ')' key_options
 	  {
 	    LEX *lex=Lex;
-	    const char *key_name= $3 ? $3:$1;
-	    lex->key_list.push_back(new Key($2, key_name, $4, 0,
-				    lex->col_list));
+	    const char *key_name= $3 ? $3 : $1;
+	    lex->key_list.push_back(new Key($2, key_name, &lex->key_create_info, 0,
+					    lex->col_list));
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
 	  }
 	| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
@@ -4012,7 +4024,7 @@ key_def:
 				    lex->fk_update_opt,
 				    lex->fk_match_option));
 	    lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1,
-					    HA_KEY_ALG_UNDEF, 1,
+					    &default_key_create_info, 1,
 					    lex->col_list));
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
 
@@ -4029,20 +4041,6 @@ key_def:
 	  }
 	;
 
-opt_fulltext_parser:
-        /* empty */               { $$= (LEX_STRING *)0; }
-	| WITH PARSER_SYM IDENT_sys
-          {
-            if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
-              $$= (LEX_STRING *)sql_memdup(&$3, sizeof(LEX_STRING));
-            else
-            {
-              my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
-              YYABORT;
-            }
-          }
-        ;
-
 opt_check_constraint:
 	/* empty */
 	| check_constraint
@@ -4516,10 +4514,50 @@ opt_unique_or_fulltext:
 	  }
         ;
 
+init_key_options:
+	{
+	  Lex->key_create_info= default_key_create_info;
+	}
+	;
+
+/*
+  For now, key_alg initializies lex->key_create_info.
+  In the future, when all key options are after key definition,
+  we can remove key_alg and move init_key_options to key_options
+*/
+
 key_alg:
-	/* empty */		   { $$= HA_KEY_ALG_UNDEF; }
-	| USING opt_btree_or_rtree { $$= $2; }
-	| TYPE_SYM opt_btree_or_rtree  { $$= $2; };
+	/* empty */ init_key_options
+	| init_key_options key_opts
+	;
+
+key_options:
+	/* empty */ {}
+	| key_opts
+	;
+
+key_opts:
+	key_opt
+	| key_opts key_opt
+	;
+	
+key_opt:
+	USING opt_btree_or_rtree       { Lex->key_create_info.algorithm= $2; }
+	| TYPE_SYM opt_btree_or_rtree  { Lex->key_create_info.algorithm= $2; }
+	| KEY_BLOCK_SIZE opt_equal ulong_num
+	  { Lex->key_create_info.block_size= $3; }
+	| WITH PARSER_SYM IDENT_sys
+          {
+            if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
+              Lex->key_create_info.parser_name= $3;
+            else
+            {
+              my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
+              YYABORT;
+            }
+          }
+        ;
+
 
 opt_btree_or_rtree:
 	BTREE_SYM	{ $$= HA_KEY_ALG_BTREE; }
@@ -8038,7 +8076,7 @@ show_param:
             if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
               YYABORT;
 	  }
-        | PLUGIN_SYM
+        | opt_full PLUGIN_SYM
 	  {
 	    LEX *lex= Lex;
 	    WARN_DEPRECATED(yythd, "5.2", "SHOW PLUGIN", "'SHOW PLUGINS'");
@@ -9348,7 +9386,7 @@ keyword_sp:
 	| ISSUER_SYM		{}
 	| INNOBASE_SYM		{}
 	| INSERT_METHOD		{}
-	| RELAY_THREAD		{}
+	| KEY_BLOCK_SIZE	{}
 	| LAST_SYM		{}
 	| LEAVES                {}
 	| LESS_SYM		{}
@@ -9435,6 +9473,7 @@ keyword_sp:
         | REDUNDANT_SYM         {}
 	| RELAY_LOG_FILE_SYM	{}
 	| RELAY_LOG_POS_SYM	{}
+	| RELAY_THREAD		{}
 	| RELOAD		{}
 	| REORGANIZE_SYM	{}
 	| REPEATABLE_SYM	{}
diff --git a/sql/structs.h b/sql/structs.h
index e369d8ed7e8..72237887514 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -86,6 +86,7 @@ typedef struct st_key {
   uint	key_parts;			/* How many key_parts */
   uint  extra_length;
   uint	usable_key_parts;		/* Should normally be = key_parts */
+  uint  block_size;
   enum  ha_key_alg algorithm;
   /*
     Note that parser is used when the table is opened for use, and
diff --git a/sql/table.cc b/sql/table.cc
index 6ba66569f5c..bacb703a28c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -535,6 +535,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
       keyinfo->key_length= (uint) uint2korr(strpos+2);
       keyinfo->key_parts=  (uint) strpos[4];
       keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
+      keyinfo->block_size= uint2korr(strpos+6);
       strpos+=8;
     }
     else
@@ -706,6 +707,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
     }
     my_free(buff, MYF(0));
   }
+  share->key_block_size= uint2korr(head+62);
 
   error=4;
   extra_rec_buf_length= uint2korr(head+59);
@@ -2065,6 +2067,11 @@ File create_frm(THD *thd, const char *name, const char *db,
     tmp= MYSQL_VERSION_ID;          // Store to avoid warning from int4store
     int4store(fileinfo+51, tmp);
     int4store(fileinfo+55, create_info->extra_size);
+    /*
+      59-60 is reserved for extra_rec_buf_length,
+      61 for default_part_db_type
+    */
+    int2store(fileinfo+62, create_info->key_block_size);
     bzero(fill,IO_SIZE);
     for (; length > IO_SIZE ; length-= IO_SIZE)
     {
diff --git a/sql/table.h b/sql/table.h
index aec9a7115e6..5fd9cd28585 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -160,6 +160,7 @@ typedef struct st_table_share
   uint ref_count;                       /* How many TABLE objects uses this */
   uint open_count;			/* Number of tables in open list */
   uint blob_ptr_size;			/* 4 or 8 */
+  uint key_block_size;			/* create key_block_size, if used */
   uint null_bytes, last_null_bit_pos;
   uint fields;				/* Number of fields */
   uint rec_buff_length;                 /* Size of table->record[] buffer */
@@ -335,7 +336,8 @@ typedef struct st_foreign_key_info
   LEX_STRING *forein_id;
   LEX_STRING *referenced_db;
   LEX_STRING *referenced_table;
-  LEX_STRING *constraint_method;
+  LEX_STRING *update_method;
+  LEX_STRING *delete_method;
   List foreign_fields;
   List referenced_fields;
 } FOREIGN_KEY_INFO;
@@ -359,6 +361,7 @@ enum enum_schema_tables
   SCH_PARTITIONS,
   SCH_PLUGINS,
   SCH_PROCESSLIST,
+  SCH_REFERENTIAL_CONSTRAINTS,
   SCH_PROCEDURES,
   SCH_SCHEMATA,
   SCH_SCHEMA_PRIVILEGES,
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 1be2321200b..228a8cd9b92 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1382,11 +1382,30 @@ static LS_INFO *tz_lsis= 0;
 static bool time_zone_tables_exist= 1;
 
 
-typedef struct st_tz_names_entry: public Sql_alloc
+/*
+  Names of tables (with their lengths) that are needed
+  for dynamical loading of time zone descriptions.
+*/
+
+static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]=
 {
+  {(char *) STRING_WITH_LEN("time_zone_name")},
+  {(char *) STRING_WITH_LEN("time_zone")},
+  {(char *) STRING_WITH_LEN("time_zone_transition_type")},
+  {(char *) STRING_WITH_LEN("time_zone_transition")}
+};
+
+/* Name of database to which those tables belong. */
+
+static const LEX_STRING tz_tables_db_name= {(char *) STRING_WITH_LEN("mysql")};
+
+
+class Tz_names_entry: public Sql_alloc
+{
+public:
   String name;
   Time_zone *tz;
-} TZ_NAMES_ENTRY;
+};
 
 
 /*
@@ -1394,7 +1413,7 @@ typedef struct st_tz_names_entry: public Sql_alloc
   they should obey C calling conventions.
 */
 
-extern "C" byte* my_tz_names_get_key(TZ_NAMES_ENTRY *entry, uint *length,
+extern "C" byte* my_tz_names_get_key(Tz_names_entry *entry, uint *length,
                               my_bool not_used __attribute__((unused)))
 {
   *length= entry->name.length();
@@ -1415,7 +1434,8 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
 
   SYNOPSIS
     tz_init_table_list()
-      tz_tabs         - pointer to preallocated array of 4 TABLE_LIST objects
+      tz_tabs         - pointer to preallocated array of MY_TZ_TABLES_COUNT
+                        TABLE_LIST objects
       global_next_ptr - pointer to variable which points to global_next member
                         of last element of global table list (or list root
                         then list is empty) (in/out).
@@ -1430,27 +1450,27 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
 static void
 tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
 {
-  bzero(tz_tabs, sizeof(TABLE_LIST) * 4);
-  tz_tabs[0].alias= tz_tabs[0].table_name= (char*)"time_zone_name";
-  tz_tabs[1].alias= tz_tabs[1].table_name= (char*)"time_zone";
-  tz_tabs[2].alias= tz_tabs[2].table_name= (char*)"time_zone_transition_type";
-  tz_tabs[3].alias= tz_tabs[3].table_name= (char*)"time_zone_transition";
-  tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1;
-  tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2;
-  tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3;
-  tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type=
-    tz_tabs[3].lock_type= TL_READ;
-  tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql";
+  bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT);
+
+  for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
+  {
+    tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i].str;
+    tz_tabs[i].table_name_length= tz_tables_names[i].length;
+    tz_tabs[i].db= tz_tables_db_name.str;
+    tz_tabs[i].db_length= tz_tables_db_name.length;
+    tz_tabs[i].lock_type= TL_READ;
+
+    if (i != MY_TZ_TABLES_COUNT - 1)
+      tz_tabs[i].next_global= tz_tabs[i].next_local= &tz_tabs[i+1];
+    if (i != 0)
+      tz_tabs[i].prev_global= &tz_tabs[i-1].next_global;
+  }
 
   /* Link into global list */
   tz_tabs[0].prev_global= *global_next_ptr;
-  tz_tabs[1].prev_global= &tz_tabs[0].next_global;
-  tz_tabs[2].prev_global= &tz_tabs[1].next_global;
-  tz_tabs[3].prev_global= &tz_tabs[2].next_global;
-
   **global_next_ptr= tz_tabs;
   /* Update last-global-pointer to point to pointer in last table */
-  *global_next_ptr= &tz_tabs[3].next_global;
+  *global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global;
 }
 
 
@@ -1479,7 +1499,8 @@ TABLE_LIST fake_time_zone_tables_list;
 
   NOTE
     my_tz_check_n_skip_implicit_tables() function depends on fact that
-    elements of list created are allocated as TABLE_LIST[4] array.
+    elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT]
+    array.
 
   RETURN VALUES
     Returns pointer to first TABLE_LIST object, (could be 0 if time zone
@@ -1495,7 +1516,8 @@ my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr)
   if (!time_zone_tables_exist)
     DBUG_RETURN(0);
 
-  if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4)))
+  if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) *
+                                          MY_TZ_TABLES_COUNT)))
     DBUG_RETURN(&fake_time_zone_tables_list);
 
   tz_init_table_list(tz_tabs, global_next_ptr);
@@ -1534,9 +1556,9 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
 {
   THD *thd;
   TABLE_LIST *tables= 0;
-  TABLE_LIST tables_buff[5], **last_global_next_ptr;
+  TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr;
   TABLE *table;
-  TZ_NAMES_ENTRY *tmp_tzname;
+  Tz_names_entry *tmp_tzname;
   my_bool return_val= 1;
   int res;
   DBUG_ENTER("my_tz_init");
@@ -1568,7 +1590,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
   tz_inited= 1;
 
   /* Add 'SYSTEM' time zone to tz_names hash */
-  if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY()))
+  if (!(tmp_tzname= new (&tz_storage) Tz_names_entry()))
   {
     sql_print_error("Fatal error: OOM while initializing time zones");
     goto end_with_cleanup;
@@ -1764,7 +1786,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
 {
   TABLE *table= 0;
   TIME_ZONE_INFO *tz_info;
-  TZ_NAMES_ENTRY *tmp_tzname;
+  Tz_names_entry *tmp_tzname;
   Time_zone *return_val= 0;
   int res;
   uint tzid, ttid;
@@ -2039,7 +2061,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
   }
 
 
-  if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY()) ||
+  if (!(tmp_tzname= new (&tz_storage) Tz_names_entry()) ||
       !(tmp_tzname->tz= new (&tz_storage) Time_zone_db(tz_info,
                                             &(tmp_tzname->name))) ||
       (tmp_tzname->name.set(tz_name_buff, tz_name->length(),
@@ -2186,7 +2208,7 @@ str_to_offset(const char *str, uint length, long *offset)
 Time_zone *
 my_tz_find(const String * name, TABLE_LIST *tz_tables)
 {
-  TZ_NAMES_ENTRY *tmp_tzname;
+  Tz_names_entry *tmp_tzname;
   Time_zone *result_tz= 0;
   long offset;
   DBUG_ENTER("my_tz_find");
@@ -2221,7 +2243,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
   else
   {
     result_tz= 0;
-    if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names,
+    if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names,
                                                    (const byte *)name->ptr(),
                                                    name->length())))
       result_tz= tmp_tzname->tz;
@@ -2273,7 +2295,7 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
       our time zone tables. Note that if we don't have tz tables on this
       slave, we don't even try.
     */
-    TABLE_LIST tables[4];
+    TABLE_LIST tables[MY_TZ_TABLES_COUNT];
     TABLE_LIST *dummy;
     TABLE_LIST **dummyp= &dummy;
     tz_init_table_list(tables, &dummyp);
diff --git a/sql/tztime.h b/sql/tztime.h
index 42e50988e52..95184c9b3d1 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -69,6 +69,15 @@ extern my_time_t   sec_since_epoch_TIME(TIME *t);
 
 extern TABLE_LIST fake_time_zone_tables_list;
 
+/*
+  Number of elements in table list produced by my_tz_get_table_list()
+  (this table list contains tables which are needed for dynamical loading
+  of time zone descriptions). Actually it is imlementation detail that
+  should not be used anywhere outside of tztime.h and tztime.cc.
+*/
+
+static const int MY_TZ_TABLES_COUNT= 4;
+
 /*
   Check if we have pointer to the begining of list of implicitly used time
   zone tables, set SELECT_ACL for them and fast-forward to its end.
@@ -91,9 +100,9 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
 {
   if (*table == tz_tables)
   {
-    for (int i= 0; i < 4; i++)
+    for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
       (*table)[i].grant.privilege= SELECT_ACL;
-    (*table)+= 3;
+    (*table)+= MY_TZ_TABLES_COUNT - 1;
     return TRUE;
   }
   return FALSE;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index bbb4d970d37..eb38e6c0592 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -338,9 +338,9 @@ err_handler:
 
 	/* Pack screens to a screen for save in a form-file */
 
-static uchar * pack_screens(List &create_fields,
-			    uint *info_length, uint *screens,
-			    bool small_file)
+static uchar *pack_screens(List &create_fields,
+                           uint *info_length, uint *screens,
+                           bool small_file)
 {
   reg1 uint i;
   uint row,start_row,end_row,fields_on_screen;
@@ -431,7 +431,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
     int2store(pos+2,key->key_length);
     pos[4]= (uchar) key->key_parts;
     pos[5]= (uchar) key->algorithm;
-    pos[6]=pos[7]=0;				// For the future
+    int2store(pos+6, key->block_size);
     pos+=8;
     key_parts+=key->key_parts;
     DBUG_PRINT("loop",("flags: %d  key_parts: %d at 0x%lx",
diff --git a/storage/archive/Makefile.am b/storage/archive/Makefile.am
index 415e0dc8f8f..85577f406da 100644
--- a/storage/archive/Makefile.am
+++ b/storage/archive/Makefile.am
@@ -14,20 +14,49 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include \
-			@ZLIB_INCLUDES@
+#called from the top level Makefile
 
-LDADD =			libarchive.a \
-			$(top_builddir)/mysys/libmysys.a \
+MYSQLDATAdir =          $(localstatedir)
+MYSQLSHAREdir =         $(pkgdatadir)
+MYSQLBASEdir=           $(prefix)
+MYSQLLIBdir=            $(pkglibdir)
+INCLUDES =              -I$(top_srcdir)/include -I$(top_builddir)/include \
+			-I$(top_srcdir)/regex \
+			-I$(top_srcdir)/sql \
+                        -I$(srcdir) @ZLIB_INCLUDES@
+WRAPLIBS=
+
+LDADD =
+
+DEFS =                  @DEFS@
+
+noinst_HEADERS =	ha_archive.h azlib.h
+noinst_PROGRAMS	=	archive_test
+
+EXTRA_LTLIBRARIES =	ha_archive.la
+pkglib_LTLIBRARIES =	@plugin_archive_shared_target@
+ha_archive_la_LDFLAGS =	-module -rpath $(MYSQLLIBdir)
+ha_archive_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_archive_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_archive_la_SOURCES =	ha_archive.cc azio.c
+
+
+EXTRA_LIBRARIES =	libarchive.a
+noinst_LIBRARIES =	@plugin_archive_static_target@
+libarchive_a_CXXFLAGS =	$(AM_CFLAGS)
+libarchive_a_CFLAGS =	$(AM_CFLAGS)
+libarchive_a_SOURCES =	ha_archive.cc azio.c
+
+
+archive_test_SOURCES =	archive_test.c azio.c
+archive_test_CFLAGS =	$(AM_CFLAGS)
+archive_test_LDADD =	$(top_builddir)/mysys/libmysys.a \
 			$(top_builddir)/dbug/libdbug.a \
 			$(top_builddir)/strings/libmystrings.a \
 			@ZLIB_LIBS@
-pkglib_LIBRARIES =	libarchive.a
-noinst_PROGRAMS	=	archive_test
 archive_test_LDFLAGS = @NOINST_LDFLAGS@
-noinst_HEADERS =	azlib.h
-libarchive_a_SOURCES =	azio.c
-EXTRA_DIST =		cmakelists.txt
 
+
+EXTRA_DIST =		cmakelists.txt
 # Don't update the files from bitkeeper
 %::SCCS/s.%
diff --git a/storage/archive/cmakelists.txt b/storage/archive/cmakelists.txt
index 4189781e73a..a631f194b1a 100644
--- a/storage/archive/cmakelists.txt
+++ b/storage/archive/cmakelists.txt
@@ -1,6 +1,8 @@
 SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
 SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
 
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib)
-ADD_LIBRARY(archive azio.c)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
+                    ${CMAKE_SOURCE_DIR}/sql
+                    ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ADD_LIBRARY(archive azio.c ha_archive.cc ha_archive.h)
 TARGET_LINK_LIBRARIES(archive zlib mysys dbug strings)
diff --git a/sql/ha_archive.cc b/storage/archive/ha_archive.cc
similarity index 94%
rename from sql/ha_archive.cc
rename to storage/archive/ha_archive.cc
index 942faaae517..e39ee976eb1 100644
--- a/sql/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -19,10 +19,13 @@
 #endif
 
 #include "mysql_priv.h"
+#include 
 
 #include "ha_archive.h"
 #include 
 
+#include 
+
 /*
   First, if you want to understand storage engines you should look at 
   ha_example.cc and ha_example.h. 
@@ -143,12 +146,15 @@ static handler *archive_create_handler(TABLE_SHARE *table);
 #define ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT 2
 
 
+static const char archive_hton_name[]= "ARCHIVE";
+static const char archive_hton_comment[]= "Archive storage engine";
+
 /* dummy handlerton - only to have something to return from archive_db_init */
 handlerton archive_hton = {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "ARCHIVE",
+  archive_hton_name,
   SHOW_OPTION_YES,
-  "Archive storage engine", 
+  archive_hton_comment, 
   DB_TYPE_ARCHIVE_DB,
   archive_db_init,
   0,       /* slot */
@@ -214,6 +220,8 @@ static byte* archive_get_key(ARCHIVE_SHARE *share,uint *length,
 bool archive_db_init()
 {
   DBUG_ENTER("archive_db_init");
+  if (archive_inited)
+    DBUG_RETURN(FALSE);
   if (pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST))
     goto error;
   if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
@@ -227,7 +235,6 @@ bool archive_db_init()
     DBUG_RETURN(FALSE);
   }
 error:
-  have_archive_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
   DBUG_RETURN(TRUE);
 }
 
@@ -235,14 +242,14 @@ error:
   Release the archive handler.
 
   SYNOPSIS
-    archive_db_end()
+    archive_db_done()
     void
 
   RETURN
     FALSE       OK
 */
 
-int archive_db_end(ha_panic_function type)
+int archive_db_done()
 {
   if (archive_inited)
   {
@@ -253,6 +260,12 @@ int archive_db_end(ha_panic_function type)
   return 0;
 }
 
+
+int archive_db_end(ha_panic_function type)
+{
+  return archive_db_done();
+}
+
 ha_archive::ha_archive(TABLE_SHARE *table_arg)
   :handler(&archive_hton, table_arg), delayed_insert(0), bulk_insert(0)
 {
@@ -459,12 +472,11 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name,
     share->table_name_length= length;
     share->table_name= tmp_name;
     share->crashed= FALSE;
+    share->archive_write_open= FALSE;
     fn_format(share->data_file_name, table_name, "",
               ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME);
     fn_format(meta_file_name, table_name, "", ARM,
               MY_REPLACE_EXT|MY_UNPACK_FILENAME);
-    DBUG_PRINT("info", ("archive opening (1) up write at %s", 
-                        share->data_file_name));
     strmov(share->table_name,table_name);
     /*
       We will use this lock for rows.
@@ -476,38 +488,20 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name,
                         share->data_file_name));
     
     /*
-      After we read, we set the file to dirty. When we close, we will do the 
-      opposite. If the meta file will not open we assume it is crashed and
-      leave it up to the user to fix.
+      We read the meta file, but do not mark it dirty unless we actually do
+      a write.
     */
     if (read_meta_file(share->meta_file, &share->rows_recorded, 
                        &share->auto_increment_value,
                        &share->forced_flushes,
                        share->real_path))
       share->crashed= TRUE;
-    else
-      (void)write_meta_file(share->meta_file, share->rows_recorded,
-                            share->auto_increment_value, 
-                            share->forced_flushes, 
-                            share->real_path,
-                            TRUE);
     /*
       Since we now possibly no real_path, we will use it instead if it exists.
     */
     if (*share->real_path)
       fn_format(share->data_file_name, share->real_path, "", ARZ,
                 MY_REPLACE_EXT|MY_UNPACK_FILENAME);
-    /* 
-      It is expensive to open and close the data files and since you can't have
-      a gzip file that can be both read and written we keep a writer open
-      that is shared amoung all open tables.
-    */
-    if (!(azopen(&(share->archive_write), share->data_file_name, 
-                 O_WRONLY|O_APPEND|O_BINARY)))
-    {
-      DBUG_PRINT("info", ("Could not open archive write file"));
-      share->crashed= TRUE;
-    }
     VOID(my_hash_insert(&archive_open_tables, (byte*) share));
     thr_lock_init(&share->lock);
   }
@@ -554,8 +548,9 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
                           share->forced_flushes, 
                           share->real_path, 
                           share->crashed ? TRUE :FALSE);
-    if (azclose(&(share->archive_write)))
-      rc= 1;
+    if (share->archive_write_open)
+      if (azclose(&(share->archive_write)))
+        rc= 1;
     if (my_close(share->meta_file, MYF(0)))
       rc= 1;
     my_free((gptr) share, MYF(0));
@@ -565,6 +560,32 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
   DBUG_RETURN(rc);
 }
 
+int ha_archive::init_archive_writer()
+{
+  DBUG_ENTER("ha_archive::init_archive_writer");
+  (void)write_meta_file(share->meta_file, share->rows_recorded,
+                        share->auto_increment_value, 
+                        share->forced_flushes, 
+                        share->real_path,
+                        TRUE);
+
+  /* 
+    It is expensive to open and close the data files and since you can't have
+    a gzip file that can be both read and written we keep a writer open
+    that is shared amoung all open tables.
+  */
+  if (!(azopen(&(share->archive_write), share->data_file_name, 
+               O_WRONLY|O_APPEND|O_BINARY)))
+  {
+    DBUG_PRINT("info", ("Could not open archive write file"));
+    share->crashed= TRUE;
+    DBUG_RETURN(1);
+  }
+  share->archive_write_open= TRUE;
+
+  DBUG_RETURN(0);
+}
+
 
 /*
   We just implement one additional file extension.
@@ -830,7 +851,7 @@ int ha_archive::write_row(byte *buf)
   if (share->crashed)
       DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
-  statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
+  ha_statistic_increment(&SSV::ha_write_count);
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
     table->timestamp_field->set_time();
   pthread_mutex_lock(&share->mutex);
@@ -910,6 +931,9 @@ int ha_archive::write_row(byte *buf)
     Notice that the global auto_increment has been increased.
     In case of a failed row write, we will never try to reuse the value.
   */
+  if (!share->archive_write_open)
+    if (init_archive_writer())
+      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
   share->rows_recorded++;
   rc= real_write_row(buf, &(share->archive_write));
@@ -1147,8 +1171,7 @@ int ha_archive::rnd_next(byte *buf)
     DBUG_RETURN(HA_ERR_END_OF_FILE);
   scan_rows--;
 
-  statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
-		      &LOCK_status);
+  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
   current_position= aztell(&archive);
   rc= get_row(&archive, buf);
 
@@ -1184,8 +1207,7 @@ void ha_archive::position(const byte *record)
 int ha_archive::rnd_pos(byte * buf, byte *pos)
 {
   DBUG_ENTER("ha_archive::rnd_pos");
-  statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
-		      &LOCK_status);
+  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
   current_position= (my_off_t)my_get_ptr(pos, ref_length);
   (void)azseek(&archive, current_position, SEEK_SET);
 
@@ -1221,6 +1243,10 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
   azio_stream writer;
   char writer_filename[FN_REFLEN];
 
+  /* Open up the writer if we haven't yet */
+  if (!share->archive_write_open)
+    init_archive_writer();
+
   /* Flush any waiting data */
   azflush(&(share->archive_write), Z_SYNC_FLUSH);
   share->forced_flushes++;
@@ -1369,8 +1395,8 @@ THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
     */
 
     if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
-         lock_type <= TL_WRITE) && !thd->in_lock_tables
-        && !thd->tablespace_op)
+         lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
+        && !thd_tablespace_op(thd))
       lock_type = TL_WRITE_ALLOW_WRITE;
 
     /* 
@@ -1381,7 +1407,7 @@ THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
       concurrent inserts to t2. 
     */
 
-    if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) 
+    if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd)) 
       lock_type = TL_READ;
 
     lock.type=lock_type;
@@ -1494,11 +1520,11 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
 {
   int rc= 0;
   byte *buf; 
-  const char *old_proc_info=thd->proc_info;
+  const char *old_proc_info;
   ha_rows count= share->rows_recorded;
   DBUG_ENTER("ha_archive::check");
 
-  thd->proc_info= "Checking table";
+  old_proc_info= thd_proc_info(thd, "Checking table");
   /* Flush any waiting data */
   azflush(&(share->archive_write), Z_SYNC_FLUSH);
   share->forced_flushes++;
@@ -1523,7 +1549,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
 
   my_free((char*)buf, MYF(0));
 
-  thd->proc_info= old_proc_info;
+  thd_proc_info(thd, old_proc_info);
 
   if ((rc && rc != HA_ERR_END_OF_FILE) || count)  
   {
@@ -1548,3 +1574,17 @@ bool ha_archive::check_and_repair(THD *thd)
 
   DBUG_RETURN(repair(thd, &check_opt));
 }
+
+
+mysql_declare_plugin(archive)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &archive_hton,
+  archive_hton_name,
+  "Brian Aker, MySQL AB",
+  archive_hton_comment,
+  NULL, /* Plugin Init */
+  archive_db_done, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+}
+mysql_declare_plugin_end;
diff --git a/sql/ha_archive.h b/storage/archive/ha_archive.h
similarity index 98%
rename from sql/ha_archive.h
rename to storage/archive/ha_archive.h
index c3f4e82d997..4663531b674 100644
--- a/sql/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -19,7 +19,7 @@
 #endif
 
 #include 
-#include "../storage/archive/azlib.h"
+#include "azlib.h"
 
 /*
   Please read ha_archive.cc first. If you are looking for more general
@@ -35,6 +35,7 @@ typedef struct st_archive_share {
   THR_LOCK lock;
   File meta_file;           /* Meta file we use */
   azio_stream archive_write;     /* Archive file we are working with */
+  bool archive_write_open;
   bool dirty;               /* Flag for if a flush should occur */
   bool crashed;             /* Meta file is crashed */
   ha_rows rows_recorded;    /* Number of rows in tables */
@@ -112,6 +113,7 @@ public:
                       bool dirty);
   ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table, int *rc);
   int free_share(ARCHIVE_SHARE *share);
+  int init_archive_writer();
   bool auto_repair() const { return 1; } // For the moment we just do this
   int read_data_header(azio_stream *file_to_read);
   int write_data_header(azio_stream *file_to_write);
diff --git a/storage/blackhole/Makefile.am b/storage/blackhole/Makefile.am
new file mode 100644
index 00000000000..902d57c1668
--- /dev/null
+++ b/storage/blackhole/Makefile.am
@@ -0,0 +1,52 @@
+# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#called from the top level Makefile
+
+MYSQLDATAdir =          $(localstatedir)
+MYSQLSHAREdir =         $(pkgdatadir)
+MYSQLBASEdir=           $(prefix)
+MYSQLLIBdir=            $(pkglibdir)
+INCLUDES =              -I$(top_srcdir)/include -I$(top_builddir)/include \
+			-I$(top_srcdir)/regex \
+			-I$(top_srcdir)/sql \
+                        -I$(srcdir)
+WRAPLIBS=
+
+LDADD =
+
+DEFS =                  @DEFS@
+
+noinst_HEADERS =	ha_blackhole.h
+
+EXTRA_LTLIBRARIES =	ha_blackhole.la
+pkglib_LTLIBRARIES =	@plugin_blackhole_shared_target@
+ha_blackhole_la_LDFLAGS=-module -rpath $(MYSQLLIBdir)
+ha_blackhole_la_CXXFLAGS=$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_blackhole_la_CFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_blackhole_la_SOURCES=ha_blackhole.cc
+
+
+EXTRA_LIBRARIES =	libblackhole.a
+noinst_LIBRARIES =	@plugin_blackhole_static_target@
+libblackhole_a_CXXFLAGS=$(AM_CFLAGS)
+libblackhole_a_CFLAGS =	$(AM_CFLAGS)
+libblackhole_a_SOURCES=	ha_blackhole.cc
+
+
+EXTRA_DIST =		cmakelists.txt
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/storage/blackhole/cmakelists.txt b/storage/blackhole/cmakelists.txt
new file mode 100644
index 00000000000..ea3a7eae38e
--- /dev/null
+++ b/storage/blackhole/cmakelists.txt
@@ -0,0 +1,6 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+                    ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ADD_LIBRARY(blackhole ha_blackhole.cc ha_blackhole.h)
diff --git a/sql/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc
similarity index 93%
rename from sql/ha_blackhole.cc
rename to storage/blackhole/ha_blackhole.cc
index 2f5e8ee0abc..e9fd1c2319d 100644
--- a/sql/ha_blackhole.cc
+++ b/storage/blackhole/ha_blackhole.cc
@@ -22,18 +22,24 @@
 #include "mysql_priv.h"
 #include "ha_blackhole.h"
 
+#include 
+
 /* Static declarations for handlerton */
 
 static handler *blackhole_create_handler(TABLE_SHARE *table);
 
 
+static const char blackhole_hton_name[]= "BLACKHOLE";
+static const char blackhole_hton_comment[]=
+  "/dev/null storage engine (anything you write to it disappears)";
+
 /* Blackhole storage engine handlerton */
 
 handlerton blackhole_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "BLACKHOLE",
+  blackhole_hton_name,
   SHOW_OPTION_YES,
-  "/dev/null storage engine (anything you write to it disappears)",
+  blackhole_hton_comment,
   DB_TYPE_BLACKHOLE_DB,
   NULL,
   0,       /* slot */
@@ -250,3 +256,15 @@ int ha_blackhole::index_last(byte * buf)
   DBUG_RETURN(HA_ERR_END_OF_FILE);
 }
 
+mysql_declare_plugin(blackhole)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &blackhole_hton,
+  blackhole_hton_name,
+  "MySQL AB",
+  blackhole_hton_comment,
+  NULL, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+}
+mysql_declare_plugin_end;
diff --git a/sql/ha_blackhole.h b/storage/blackhole/ha_blackhole.h
similarity index 100%
rename from sql/ha_blackhole.h
rename to storage/blackhole/ha_blackhole.h
diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am
index 5573df720a3..a2afeba137f 100644
--- a/storage/csv/Makefile.am
+++ b/storage/csv/Makefile.am
@@ -25,16 +25,22 @@ INCLUDES =              -I$(top_builddir)/include \
 			-I$(top_srcdir)/regex \
 			-I$(top_srcdir)/sql \
                         -I$(srcdir)
-
-pkglib_LIBRARIES =	libcsv.a
-
 LDADD =
 
 DEFS =	@DEFS@
+noinst_HEADERS	  =	ha_tina.h
 
+EXTRA_LTLIBRARIES =	ha_csv.la
+pkglib_LTLIBRARIES =	@plugin_csv_shared_target@
+ha_csv_la_LDFLAGS =	-module -rpath $(MYSQLLIBdir)
+ha_csv_la_CXXFLAGS =	$(AM_CFLAGS) -DMYSQL_PLUGIN
+ha_csv_la_SOURCES =	ha_tina.cc
+
+EXTRA_LIBRARIES =	libcsv.a
+noinst_LIBRARIES =	@plugin_csv_static_target@
 libcsv_a_CXXFLAGS =	$(AM_CFLAGS)
-noinst_HEADERS = 	ha_tina.h
 libcsv_a_SOURCES =	ha_tina.cc
 
+EXTRA_DIST =		cmakelists.txt
 # Don't update the files from bitkeeper
 %::SCCS/s.%
diff --git a/storage/csv/cmakelists.txt b/storage/csv/cmakelists.txt
index 4e142646b2d..28748527cc3 100644
--- a/storage/csv/cmakelists.txt
+++ b/storage/csv/cmakelists.txt
@@ -1,5 +1,6 @@
 SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
 SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
 
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+                    ${CMAKE_SOURCE_DIR}/extra/yassl/include)
 ADD_LIBRARY(csv ha_tina.cc ha_tina.h)
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index aed861279d9..de69df90ed5 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -77,11 +77,14 @@ static int tina_init= 0;
 static handler *tina_create_handler(TABLE_SHARE *table);
 static int tina_init_func();
 
+static const char tina_hton_name[]= "CSV";
+static const char tina_hton_comment[]= "CSV storage engine";
+
 handlerton tina_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "CSV",
+  tina_hton_name,
   SHOW_OPTION_YES,
-  "CSV storage engine", 
+  tina_hton_comment, 
   DB_TYPE_CSV_DB,
   (bool (*)()) tina_init_func,
   0,       /* slot */
@@ -1398,17 +1401,17 @@ bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info,
   return COMPATIBLE_DATA_YES;
 }
 
-#ifdef MYSQL_PLUGIN
-mysql_declare_plugin
+
+mysql_declare_plugin(csv)
 {
   MYSQL_STORAGE_ENGINE_PLUGIN,
   &tina_hton,
-  tina_hton.name,
+  tina_hton_name,
   "Brian Aker, MySQL AB",
-  "CSV Storage Engine",
+  tina_hton_comment,
   tina_init_func, /* Plugin Init */
   tina_done_func, /* Plugin Deinit */
   0x0100 /* 1.0 */,
 }
 mysql_declare_plugin_end;
-#endif
+
diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am
index 518d82abe2d..9c4bedb2160 100644
--- a/storage/example/Makefile.am
+++ b/storage/example/Makefile.am
@@ -1,15 +1,15 @@
 # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
-#
+# 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
-#
+# 
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-#
+# 
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
@@ -20,20 +20,33 @@ MYSQLDATAdir =          $(localstatedir)
 MYSQLSHAREdir =         $(pkgdatadir)
 MYSQLBASEdir=           $(prefix)
 MYSQLLIBdir=            $(pkglibdir)
-INCLUDES =              -I$(top_srcdir)/include \
+INCLUDES =              -I$(top_srcdir)/include -I$(top_builddir)/include \
 			-I$(top_srcdir)/regex \
 			-I$(top_srcdir)/sql \
                         -I$(srcdir)
 WRAPLIBS=
 
-pkglib_LIBRARIES =	libexample.a
-
-noinst_HEADERS	      =	ha_example.h
-libexample_a_SOURCES =	ha_example.cc
-EXTRA_DIST	      = cmakelists.txt
 LDADD =
 
-DEFS =                  -DMYSQL_SERVER @DEFS@
+DEFS =                  @DEFS@
 
+noinst_HEADERS =	ha_example.h
+
+EXTRA_LTLIBRARIES =	ha_example.la
+pkglib_LTLIBRARIES =	@plugin_example_shared_target@
+ha_example_la_LDFLAGS =	-module -rpath $(MYSQLLIBdir)
+ha_example_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_example_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_example_la_SOURCES =	ha_example.cc
+
+
+EXTRA_LIBRARIES =	libexample.a
+noinst_LIBRARIES =	@plugin_example_static_target@
+libexample_a_CXXFLAGS =	$(AM_CFLAGS)
+libexample_a_CFLAGS =	$(AM_CFLAGS)
+libexample_a_SOURCES=	ha_example.cc
+
+
+EXTRA_DIST =		cmakelists.txt
 # Don't update the files from bitkeeper
 %::SCCS/s.%
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index caa64c10bbd..2ce543dfbb0 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -77,11 +77,14 @@ static int example_init_func();
 static bool example_init_func_for_handlerton();
 static int example_panic(enum ha_panic_function flag);
 
+static const char example_hton_name[]= "EXAMPLE";
+static const char example_hton_comment[]= "Example storage engine";
+
 handlerton example_hton= {
   MYSQL_HANDLERTON_INTERFACE_VERSION,
-  "EXAMPLE",
+  example_hton_name,
   SHOW_OPTION_YES,
-  "Example storage engine", 
+  example_hton_comment, 
   DB_TYPE_EXAMPLE_DB,
   example_init_func_for_handlerton,
   0,       /* slot */
@@ -742,17 +745,17 @@ int ha_example::create(const char *name, TABLE *table_arg,
   DBUG_RETURN(0);
 }
 
-#ifdef MYSQL_PLUGIN
-mysql_declare_plugin
+
+mysql_declare_plugin(example)
 {
   MYSQL_STORAGE_ENGINE_PLUGIN,
   &example_hton,
-  example_hton.name,
+  example_hton_name,
   "Brian Aker, MySQL AB",
-  "Example Storage Engine",
+  example_hton_comment,
   example_init_func, /* Plugin Init */
   example_done_func, /* Plugin Deinit */
   0x0001 /* 0.1 */,
 }
 mysql_declare_plugin_end;
-#endif
+
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index 2d94418a1bf..f37db2588f3 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -79,7 +79,8 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
   custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
   custom_arg.search_flag= SEARCH_SAME;
   old_allocated= keyinfo->rb_tree.allocated;
-  res= tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg);
+  res= tree_delete(&keyinfo->rb_tree, info->recbuf, custom_arg.key_length,
+                   &custom_arg);
   info->s->index_length-= (old_allocated - keyinfo->rb_tree.allocated);
   return res;
 }
diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am
index 0cceac97688..908f5d669a2 100644
--- a/storage/innobase/Makefile.am
+++ b/storage/innobase/Makefile.am
@@ -79,5 +79,33 @@ EXTRA_DIST = 	include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr
 		include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic \
 		cmakelists.txt
 
+noinst_LIBRARIES =	libinnobase.a
+libinnobase_a_LIBADD =	usr/libusr.a srv/libsrv.a dict/libdict.a \
+			que/libque.a srv/libsrv.a ibuf/libibuf.a \
+			row/librow.a pars/libpars.a btr/libbtr.a \
+			trx/libtrx.a read/libread.a usr/libusr.a \
+			buf/libbuf.a ibuf/libibuf.a eval/libeval.a \
+			log/liblog.a fsp/libfsp.a fut/libfut.a \
+			fil/libfil.a lock/liblock.a mtr/libmtr.a \
+			page/libpage.a rem/librem.a thr/libthr.a \
+			sync/libsync.a data/libdata.a mach/libmach.a \
+			ha/libha.a dyn/libdyn.a mem/libmem.a \
+			ut/libut.a os/libos.a ut/libut.a
+libinnobase_a_SOURCES =	
+
+
+libinnobase.a:		$(libinnobase_a_LIBADD)
+		-rm -f $@
+		if test "$(host_os)" = "netware" ; \
+		then \
+		  $(libinnobase_a_AR) $@ $(libinnobase_a_LIBADD) ; \
+		else \
+		  for arc in $(libinnobase_a_LIBADD); do \
+		     arpath=`echo $$arc|sed 's|[^/]*$$||'`; \
+		     $(AR) t $$arc|sed "s|^|$$arpath|"; \
+		  done | sort -u | xargs $(AR) cq $@ ; \
+		  $(RANLIB) $@	; \
+		fi
+
 # Don't update the files from bitkeeper
 %::SCCS/s.%
diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c
index eab9d37af0b..459742d2aff 100644
--- a/storage/myisam/ft_eval.c
+++ b/storage/myisam/ft_eval.c
@@ -54,6 +54,7 @@ int main(int argc, char *argv[])
   /* Define a key over the first column */
   keyinfo[0].seg=keyseg;
   keyinfo[0].keysegs=1;
+  keyinfo[0].block_length= 0;                   /* Default block length */
   keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT;
   keyinfo[0].seg[0].flag= HA_BLOB_PART;
   keyinfo[0].seg[0].start=recinfo[0].length;
diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c
index d54b344e2cd..28dcfb2b758 100644
--- a/storage/myisam/ft_test1.c
+++ b/storage/myisam/ft_test1.c
@@ -89,6 +89,7 @@ static int run_test(const char *filename)
   /* Define a key over the first column */
   keyinfo[0].seg=keyseg;
   keyinfo[0].keysegs=1;
+  keyinfo[0].block_length= 0;                   /* Default block length */
   keyinfo[0].seg[0].type= key_type;
   keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART:
 			  (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0;
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index eb2f42697ce..0fa095a21db 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -358,7 +358,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
     puts("- check key delete-chain");
 
   param->key_file_blocks=info->s->base.keystart;
-  for (key=0 ; key < info->s->state.header.max_block_size ; key++)
+  for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
     if (check_k_link(param,info,key))
     {
       if (param->testflag & T_VERBOSE) puts("");
@@ -1411,7 +1411,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
     share->state.key_root[i]= HA_OFFSET_ERROR;
 
   /* Drop the delete chain. */
-  for (i=0 ; i < share->state.header.max_block_size ; i++)
+  for (i=0 ; i < share->state.header.max_block_size_index ; i++)
     share->state.key_del[i]=  HA_OFFSET_ERROR;
 
   /*
@@ -1795,7 +1795,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
   info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
   for (key=0 ; key < info->s->base.keys ; key++)
     info->s->state.key_root[key]=index_pos[key];
-  for (key=0 ; key < info->s->state.header.max_block_size ; key++)
+  for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
     info->s->state.key_del[key]=  HA_OFFSET_ERROR;
 
   info->s->state.changed&= ~STATE_NOT_SORTED_PAGES;
@@ -2095,7 +2095,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
     /* Clear the pointers to the given rows */
     for (i=0 ; i < share->base.keys ; i++)
       share->state.key_root[i]= HA_OFFSET_ERROR;
-    for (i=0 ; i < share->state.header.max_block_size ; i++)
+    for (i=0 ; i < share->state.header.max_block_size_index ; i++)
       share->state.key_del[i]=  HA_OFFSET_ERROR;
     info->state->key_file_length=share->base.keystart;
   }
@@ -2463,7 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
     /* Clear the pointers to the given rows */
     for (i=0 ; i < share->base.keys ; i++)
       share->state.key_root[i]= HA_OFFSET_ERROR;
-    for (i=0 ; i < share->state.header.max_block_size ; i++)
+    for (i=0 ; i < share->state.header.max_block_size_index ; i++)
       share->state.key_del[i]=  HA_OFFSET_ERROR;
     info->state->key_file_length=share->base.keystart;
   }
@@ -3800,6 +3800,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
   ha_rows max_records;
   ulonglong file_length,tmp_length;
   MI_CREATE_INFO create_info;
+  DBUG_ENTER("recreate_table");
 
   error=1;					/* Default error */
   info= **org_info;
@@ -3809,7 +3810,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
   unpack= (share.options & HA_OPTION_COMPRESS_RECORD) &&
     (param->testflag & T_UNPACK);
   if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys)))
-    return 0;
+    DBUG_RETURN(0);
   memcpy((byte*) keyinfo,(byte*) share.keyinfo,
 	 (size_t) (sizeof(MI_KEYDEF)*share.base.keys));
 
@@ -3818,14 +3819,14 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
 				       (key_parts+share.base.keys))))
   {
     my_afree((gptr) keyinfo);
-    return 1;
+    DBUG_RETURN(1);
   }
   if (!(recdef=(MI_COLUMNDEF*)
 	my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1))))
   {
     my_afree((gptr) keyinfo);
     my_afree((gptr) keysegs);
-    return 1;
+    DBUG_RETURN(1);
   }
   if (!(uniquedef=(MI_UNIQUEDEF*)
 	my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1))))
@@ -3833,7 +3834,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
     my_afree((gptr) recdef);
     my_afree((gptr) keyinfo);
     my_afree((gptr) keysegs);
-    return 1;
+    DBUG_RETURN(1);
   }
 
   /* Copy the column definitions */
@@ -3903,6 +3904,11 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
   create_info.language = (param->language ? param->language :
 			  share.state.header.language);
   create_info.key_file_length=  status_info.key_file_length;
+  /*
+    Allow for creating an auto_increment key. This has an effect only if
+    an auto_increment key exists in the original table.
+  */
+  create_info.with_auto_increment= TRUE;
   /* We don't have to handle symlinks here because we are using
      HA_DONT_TOUCH_DATA */
   if (mi_create(filename,
@@ -3947,7 +3953,7 @@ end:
   my_afree((gptr) keyinfo);
   my_afree((gptr) recdef);
   my_afree((gptr) keysegs);
-  return error;
+  DBUG_RETURN(error);
 }
 
 
@@ -4050,6 +4056,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
 			       my_bool repair_only)
 {
   byte *record;
+  DBUG_ENTER("update_auto_increment_key");
+
   if (!info->s->base.auto_key ||
       ! mi_is_key_active(info->s->state.key_map, info->s->base.auto_key - 1))
   {
@@ -4057,7 +4065,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
       mi_check_print_info(param,
 			  "Table: %s doesn't have an auto increment key\n",
 			  param->isam_file_name);
-    return;
+    DBUG_VOID_RETURN;
   }
   if (!(param->testflag & T_SILENT) &&
       !(param->testflag & T_REP))
@@ -4070,7 +4078,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
 				  MYF(0))))
   {
     mi_check_print_error(param,"Not enough memory for extra record");
-    return;
+    DBUG_VOID_RETURN;
   }
 
   mi_extra(info,HA_EXTRA_KEYREAD,0);
@@ -4081,7 +4089,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
       mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
       my_free((char*) record, MYF(0));
       mi_check_print_error(param,"%d when reading last record",my_errno);
-      return;
+      DBUG_VOID_RETURN;
     }
     if (!repair_only)
       info->s->state.auto_increment=param->auto_increment_value;
@@ -4097,7 +4105,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
   mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
   my_free((char*) record, MYF(0));
   update_state_info(param, info, UPDATE_AUTO_INC);
-  return;
+  DBUG_VOID_RETURN;
 }
 
 
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 3be998b2c17..22cbde278be 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -28,9 +28,9 @@
 #endif
 #include 
 
-	/*
-	** Old options is used when recreating database, from isamchk
-	*/
+/*
+  Old options is used when recreating database, from myisamchk
+*/
 
 int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
 	      uint columns, MI_COLUMNDEF *recinfo,
@@ -45,6 +45,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
        key_length,info_length,key_segs,options,min_key_length_skip,
        base_pos,long_varchar_count,varchar_length,
        max_key_block_length,unique_key_parts,fulltext_keys,offset;
+  uint aligned_key_start, block_length;
   ulong reclength, real_reclength,min_pack_length;
   char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
   ulong pack_reclength;
@@ -428,8 +429,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
 	key_segs)
       share.state.rec_per_key_part[key_segs-1]=1L;
     length+=key_length;
+    /* Get block length for key, if defined by user */
+    block_length= (keydef->block_length ? 
+                   my_round_up_to_next_power(keydef->block_length) :
+                   myisam_block_size);
+    block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+    block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
     keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff,
-                                        pointer,MI_MAX_KEYPTR_SIZE);
+                                        pointer,MI_MAX_KEYPTR_SIZE,
+                                        block_length);
     if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
         length >= MI_MAX_KEY_BUFF)
     {
@@ -485,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
   mi_int2store(share.state.header.base_pos,base_pos);
   share.state.header.language= (ci->language ?
 				ci->language : default_charset_info->number);
-  share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
+  share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
 
   share.state.dellink = HA_OFFSET_ERROR;
   share.state.process=	(ulong) getpid();
@@ -512,8 +521,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
   mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
 
   mi_set_all_keys_active(share.state.key_map, keys);
-  share.base.keystart = share.state.state.key_file_length=
-    MY_ALIGN(info_length, myisam_block_size);
+  aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
+                                               max_key_block_length :
+                                               myisam_block_size);
+
+  share.base.keystart= share.state.state.key_file_length=
+    MY_ALIGN(info_length, aligned_key_start);
   share.base.max_key_block_length=max_key_block_length;
   share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
   share.base.records=ci->max_rows;
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index f8463a0b6b0..526a733e724 100644
--- a/storage/myisam/mi_key.c
+++ b/storage/myisam/mi_key.c
@@ -127,7 +127,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
     }
     if (keyseg->flag & HA_VAR_LENGTH_PART)
     {
-      uint pack_length= keyseg->bit_start;
+      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
       uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
                         uint2korr(pos));
       pos+= pack_length;			/* Skip VARCHAR length */
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 91bf438035f..b61c1af24da 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -295,7 +295,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
 			 &share->data_file_name,strlen(data_name)+1,
 			 &share->state.key_root,keys*sizeof(my_off_t),
 			 &share->state.key_del,
-			 (share->state.header.max_block_size*sizeof(my_off_t)),
+			 (share->state.header.max_block_size_index*sizeof(my_off_t)),
 #ifdef THREAD
 			 &share->key_root_lock,sizeof(rw_lock_t)*keys,
 #endif
@@ -310,7 +310,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
 	   (char*) key_root, sizeof(my_off_t)*keys);
     memcpy((char*) share->state.key_del,
 	   (char*) key_del, (sizeof(my_off_t) *
-			     share->state.header.max_block_size));
+			     share->state.header.max_block_size_index));
     strmov(share->unique_file_name, name_buff);
     share->unique_name_length= strlen(name_buff);
     strmov(share->index_file_name,  index_name);
@@ -820,7 +820,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
   uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
   uchar *ptr=buff;
   uint	i, keys= (uint) state->header.keys,
-	key_blocks=state->header.max_block_size;
+	key_blocks=state->header.max_block_size_index;
   DBUG_ENTER("mi_state_info_write");
 
   memcpy_fixed(ptr,&state->header,sizeof(state->header));
@@ -886,7 +886,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
   ptr +=sizeof(state->header);
   keys=(uint) state->header.keys;
   key_parts=mi_uint2korr(state->header.key_parts);
-  key_blocks=state->header.max_block_size;
+  key_blocks=state->header.max_block_size_index;
 
   state->open_count = mi_uint2korr(ptr);	ptr +=2;
   state->changed= (bool) *ptr++;
@@ -1059,7 +1059,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
    keydef->keylength	= mi_uint2korr(ptr);	ptr +=2;
    keydef->minlength	= mi_uint2korr(ptr);	ptr +=2;
    keydef->maxlength	= mi_uint2korr(ptr);	ptr +=2;
-   keydef->block_size	= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
+   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
    keydef->underflow_block_length=keydef->block_length/3;
    keydef->version	= 0;			/* Not saved */
    keydef->parser       = &ft_default_parser;
diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c
index 5240c063fba..a5e2b01ed0f 100644
--- a/storage/myisam/mi_page.c
+++ b/storage/myisam/mi_page.c
@@ -112,8 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos,
   DBUG_ENTER("_mi_dispose");
   DBUG_PRINT("enter",("pos: %ld", (long) pos));
 
-  old_link=info->s->state.key_del[keyinfo->block_size];
-  info->s->state.key_del[keyinfo->block_size]=pos;
+  old_link= info->s->state.key_del[keyinfo->block_size_index];
+  info->s->state.key_del[keyinfo->block_size_index]= pos;
   mi_sizestore(buff,old_link);
   info->s->state.changed|= STATE_NOT_SORTED_PAGES;
   DBUG_RETURN(key_cache_write(info->s->key_cache,
@@ -132,7 +132,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
   char buff[8];
   DBUG_ENTER("_mi_new");
 
-  if ((pos=info->s->state.key_del[keyinfo->block_size]) == HA_OFFSET_ERROR)
+  if ((pos= info->s->state.key_del[keyinfo->block_size_index]) ==
+      HA_OFFSET_ERROR)
   {
     if (info->state->key_file_length >=
 	info->s->base.max_key_file_length - keyinfo->block_length)
@@ -152,7 +153,7 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
 			(uint) keyinfo->block_length,0))
       pos= HA_OFFSET_ERROR;
     else
-      info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff);
+      info->s->state.key_del[keyinfo->block_size_index]= mi_sizekorr(buff);
   }
   info->s->state.changed|= STATE_NOT_SORTED_PAGES;
   DBUG_PRINT("exit",("Pos: %ld",(long) pos));
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 0e62b074376..0b78ac8a7ff 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -95,6 +95,7 @@ static int run_test(const char *filename)
   /* Define a key over the first column */
   keyinfo[0].seg=keyseg;
   keyinfo[0].keysegs=1;
+  keyinfo[0].block_length= 0;                   /* Default block length */
   keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[0].seg[0].type= key_type;
   keyinfo[0].seg[0].flag= pack_seg;
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index e77a37d853f..357ebb1b9bc 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -95,6 +95,7 @@ int main(int argc, char *argv[])
   keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[0].keysegs=1;
   keyinfo[0].flag = pack_type;
+  keyinfo[0].block_length= 0;                   /* Default block length */
   keyinfo[1].seg= &glob_keyseg[1][0];
   keyinfo[1].seg[0].start=7;
   keyinfo[1].seg[0].length=6;
@@ -111,6 +112,7 @@ int main(int argc, char *argv[])
   keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[1].keysegs=2;
   keyinfo[1].flag =0;
+  keyinfo[1].block_length= MI_MIN_KEY_BLOCK_LENGTH;  /* Diff blocklength */
   keyinfo[2].seg= &glob_keyseg[2][0];
   keyinfo[2].seg[0].start=12;
   keyinfo[2].seg[0].length=8;
@@ -121,6 +123,7 @@ int main(int argc, char *argv[])
   keyinfo[2].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[2].keysegs=1;
   keyinfo[2].flag =HA_NOSAME;
+  keyinfo[2].block_length= 0;                   /* Default block length */
   keyinfo[3].seg= &glob_keyseg[3][0];
   keyinfo[3].seg[0].start=0;
   keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0);
@@ -132,6 +135,7 @@ int main(int argc, char *argv[])
   keyinfo[3].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[3].keysegs=1;
   keyinfo[3].flag = pack_type;
+  keyinfo[3].block_length= 0;                   /* Default block length */
   keyinfo[4].seg= &glob_keyseg[4][0];
   keyinfo[4].seg[0].start=0;
   keyinfo[4].seg[0].length=5;
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
   keyinfo[4].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[4].keysegs=1;
   keyinfo[4].flag = pack_type;
+  keyinfo[4].block_length= 0;                   /* Default block length */
   keyinfo[5].seg= &glob_keyseg[5][0];
   keyinfo[5].seg[0].start=0;
   keyinfo[5].seg[0].length=4;
@@ -154,6 +159,7 @@ int main(int argc, char *argv[])
   keyinfo[5].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[5].keysegs=1;
   keyinfo[5].flag = pack_type;
+  keyinfo[5].block_length= 0;                   /* Default block length */
 
   recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
   recinfo[0].length=7;
@@ -813,7 +819,7 @@ end:
     printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
     if (rec_pointer_size)
       printf("Record pointer size:  %d\n",rec_pointer_size);
-    printf("myisam_block_size:    %u\n", myisam_block_size);
+    printf("myisam_block_size:    %lu\n", myisam_block_size);
     if (key_cacheing)
     {
       puts("Key cache used");
@@ -914,13 +920,13 @@ static void get_options(int argc, char **argv)
       }
       break;
     case 'e':				/* myisam_block_length */
-      if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
+      if ((myisam_block_size= atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
 	  myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH)
       {
 	fprintf(stderr,"Wrong myisam_block_length\n");
 	exit(1);
       }
-      myisam_block_size=1 << my_bit_log2(myisam_block_size);
+      myisam_block_size= my_round_up_to_next_power(myisam_block_size);
       break;
     case 'E':				/* myisam_block_length */
       if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
@@ -929,7 +935,7 @@ static void get_options(int argc, char **argv)
 	fprintf(stderr,"Wrong key_cache_block_size\n");
 	exit(1);
       }
-      key_cache_block_size=1 << my_bit_log2(key_cache_block_size);
+      key_cache_block_size= my_round_up_to_next_power(key_cache_block_size);
       break;
     case 'f':
       if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS)
diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c
index 4e764c6f971..173fbe64cf5 100644
--- a/storage/myisam/mi_test3.c
+++ b/storage/myisam/mi_test3.c
@@ -76,6 +76,7 @@ int main(int argc,char **argv)
   keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[0].keysegs=1;
   keyinfo[0].flag = (uint8) HA_PACK_KEY;
+  keyinfo[0].block_length= 0;                   /* Default block length */
   keyinfo[1].seg= &keyseg[1][0];
   keyinfo[1].seg[0].start=8;
   keyinfo[1].seg[0].length=4;		/* Long is always 4 in myisam */
@@ -84,6 +85,7 @@ int main(int argc,char **argv)
   keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
   keyinfo[1].keysegs=1;
   keyinfo[1].flag =HA_NOSAME;
+  keyinfo[1].block_length= 0;                   /* Default block length */
 
   recinfo[0].type=0;
   recinfo[0].length=sizeof(record.id);
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index caf6254c321..0b450de9c03 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -55,7 +55,7 @@ typedef struct st_mi_state_info
     uchar keys;				/* number of keys in file */
     uchar uniques;			/* number of UNIQUE definitions */
     uchar language;			/* Language for indexes */
-    uchar max_block_size;		/* max keyblock size */
+    uchar max_block_size_index;		/* max keyblock size */
     uchar fulltext_keys;
     uchar not_used;                     /* To align to 8 */
   } header;
@@ -431,7 +431,7 @@ typedef struct st_mi_sort_param
 #define MI_FOUND_WRONG_KEY 32738	/* Impossible value from ha_key_cmp */
 
 #define MI_MAX_KEY_BLOCK_SIZE	(MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
-#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/myisam_block_size+1)*myisam_block_size)
+#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
 #define MI_MAX_KEYPTR_SIZE	5        /* For calculating block lengths */
 #define MI_MIN_KEYBLOCK_LENGTH	50         /* When to split delete blocks */
 
@@ -742,6 +742,8 @@ my_bool check_table_is_closed(const char *name, const char *where);
 int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
 int mi_open_keyfile(MYISAM_SHARE *share);
 void mi_setup_functions(register MYISAM_SHARE *share);
+my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
+void mi_remap_file(MI_INFO *info, my_off_t size);
 
     /* Functions needed by mi_check */
 volatile int *killed_ptr(MI_CHECK *param);
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index de55b86252c..17af4ab34a2 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -475,7 +475,7 @@ static int examine_log(my_string file_name, char **table_names)
       {
 	if (!curr_file_info->closed)
 	  files_open--;
-	VOID(tree_delete(&tree, (gptr) curr_file_info, tree.custom_arg));
+        VOID(tree_delete(&tree, (gptr) curr_file_info, 0, tree.custom_arg));
       }
       break;
     case MI_LOG_EXTRA:
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index e80a3ffacd9..5b3067cb115 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -2726,6 +2726,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
 	  break;
 	}
 	case FIELD_LAST:
+        case FIELD_enum_val_count:
 	  abort();				/* Impossible */
 	}
 	start_pos+=count->max_zero_fill;
@@ -2965,7 +2966,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
   mi_clear_all_keys_active(share->state.key_map);
   for (key=0 ; key < share->base.keys ; key++)
     share->state.key_root[key]= HA_OFFSET_ERROR;
-  for (key=0 ; key < share->state.header.max_block_size ; key++)
+  for (key=0 ; key < share->state.header.max_block_size_index ; key++)
     share->state.key_del[key]= HA_OFFSET_ERROR;
   isam_file->state->checksum=crc;       /* Save crc here */
   share->changed=1;			/* Force write of header */
diff --git a/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp b/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp
index a37f3811b25..0dbc4094e67 100644
--- a/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp
+++ b/storage/ndb/include/kernel/signaldata/TcKeyReq.hpp
@@ -39,6 +39,7 @@ class TcKeyReq {
   friend class NdbOperation; 
   friend class NdbIndexOperation;
   friend class NdbScanOperation;
+  friend class NdbBlob;
   friend class DbUtil;
 
   /**
diff --git a/storage/ndb/include/mgmapi/mgmapi.h b/storage/ndb/include/mgmapi/mgmapi.h
index 75cdf60f91c..4585e78029a 100644
--- a/storage/ndb/include/mgmapi/mgmapi.h
+++ b/storage/ndb/include/mgmapi/mgmapi.h
@@ -231,6 +231,12 @@ extern "C" {
     /** Could not connect to socker */
     NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET = 1011,
 
+    /* Alloc node id failures */
+    /** Generic error, retry may succeed */
+    NDB_MGM_ALLOCID_ERROR = 1101,
+    /** Non retriable error */
+    NDB_MGM_ALLOCID_CONFIG_MISMATCH = 1102,
+
     /* Service errors - Start/Stop Node or System */
     /** Start failed */
     NDB_MGM_START_FAILED = 2001,
@@ -998,7 +1004,7 @@ extern "C" {
   void ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *);
 
   int ndb_mgm_alloc_nodeid(NdbMgmHandle handle,
-			   unsigned version, int nodetype);
+			   unsigned version, int nodetype, int log_event);
 
   /**
    * End Session
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp
index 90dca1c3fc6..010b85b03a9 100644
--- a/storage/ndb/include/ndbapi/Ndb.hpp
+++ b/storage/ndb/include/ndbapi/Ndb.hpp
@@ -1470,6 +1470,8 @@ public:
    *
    * @return tuple id or 0 on error
    */
+  int initAutoIncrement();
+
   Uint64 getAutoIncrementValue(const char* aTableName, 
 			       Uint32 cacheSize = 1);
   Uint64 getAutoIncrementValue(const NdbDictionary::Table * aTable, 
@@ -1694,6 +1696,7 @@ private:
   
   // The tupleId is retreived from DB the 
   // tupleId is unique for each tableid. 
+  const NdbDictionary::Table *m_sys_tab_0;
   Uint64               theFirstTupleId[2048]; 
   Uint64               theLastTupleId[2048];           
 
diff --git a/storage/ndb/include/ndbapi/NdbBlob.hpp b/storage/ndb/include/ndbapi/NdbBlob.hpp
index 13bbfa59e50..089b70339de 100644
--- a/storage/ndb/include/ndbapi/NdbBlob.hpp
+++ b/storage/ndb/include/ndbapi/NdbBlob.hpp
@@ -326,6 +326,7 @@ private:
   bool isWriteOp();
   bool isDeleteOp();
   bool isScanOp();
+  bool isTakeOverOp();
   // computations
   Uint32 getPartNumber(Uint64 pos);
   Uint32 getPartCount();
diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp
index b31b35cba89..b31e2551e89 100644
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp
@@ -798,6 +798,7 @@ public:
      * Get object status
      */
     virtual Object::Status getObjectStatus() const;
+    void setStatusInvalid() const;
 
     /**
      * Get object version
@@ -1734,6 +1735,7 @@ public:
      * @return 0 if successful otherwise -1.
      */
     int createIndex(const Index &index);
+    int createIndex(const Index &index, const Table &table);
 
     /**
      * Drop index with given name
@@ -1805,6 +1807,15 @@ public:
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
     const Table * getTable(const char * name, void **data) const;
     void set_local_table_data_size(unsigned sz);
+
+    const Index * getIndexGlobal(const char * indexName,
+                                 const Table &ndbtab) const;
+    const Table * getTableGlobal(const char * tableName) const;
+    int alterTableGlobal(const Table &f, const Table &t);
+    int dropTableGlobal(const Table &ndbtab);
+    int dropIndexGlobal(const Index &index);
+    int removeIndexGlobal(const Index &ndbidx, int invalidate) const;
+    int removeTableGlobal(const Table &ndbtab, int invalidate) const;
 #endif
   };
 };
diff --git a/storage/ndb/include/ndbapi/NdbIndexStat.hpp b/storage/ndb/include/ndbapi/NdbIndexStat.hpp
index c718d175864..ddd27ed24d4 100644
--- a/storage/ndb/include/ndbapi/NdbIndexStat.hpp
+++ b/storage/ndb/include/ndbapi/NdbIndexStat.hpp
@@ -56,7 +56,7 @@ public:
    * multiplied by a percentage obtained from the cache (result zero is
    * returned as 1).
    */
-  int records_in_range(NdbDictionary::Index* index,
+  int records_in_range(const NdbDictionary::Index* index,
                        NdbIndexScanOperation* op,
                        Uint64 table_rows,
                        Uint64* count,
diff --git a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
index 97de5c7f83d..e24ed5b8ddc 100644
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
@@ -355,12 +355,14 @@ ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
 	if(!ndb_mgm_connect(m_handle, 0, 0, 0))
 	  goto next;
 
-      res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
+      res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type,
+                                no_retries == 0 /* only log last retry */);
       if(res >= 0)
 	return _ownNodeId= (Uint32)res;
 
   next:
-      if (no_retries == 0)
+      int error = ndb_mgm_get_latest_error(m_handle);
+      if (no_retries == 0 || error == NDB_MGM_ALLOCID_CONFIG_MISMATCH)
 	break;
       no_retries--;
       NdbSleep_SecSleep(retry_delay_in_seconds);
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index 5f970072a19..90abe2cb809 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -484,7 +484,7 @@ Dbtup::load_diskpage(Signal* signal,
     req.m_callback.m_callbackFunction= 
       safe_cast(&Dbtup::disk_page_load_callback);
 
-#ifdef ERROR_INSERTED
+#ifdef ERROR_INSERT
     if (ERROR_INSERTED(4022))
     {
       flags |= Page_cache_client::DELAY_REQ;
diff --git a/storage/ndb/src/kernel/blocks/pgman.cpp b/storage/ndb/src/kernel/blocks/pgman.cpp
index 75a63f9d76e..addbd5e4ba2 100644
--- a/storage/ndb/src/kernel/blocks/pgman.cpp
+++ b/storage/ndb/src/kernel/blocks/pgman.cpp
@@ -1609,13 +1609,13 @@ Pgman::get_page(Signal* signal, Ptr ptr, Page_request page_req)
   }
   
   bool only_request = ptr.p->m_requests.isEmpty();
-  
+#ifdef ERROR_INSERT
   if (req_flags & Page_request::DELAY_REQ)
   {
     jam();
     only_request = false;
   }
-  
+#endif  
   if (only_request &&
       state & Page_entry::MAPPED)
   {
diff --git a/storage/ndb/src/kernel/vm/Configuration.cpp b/storage/ndb/src/kernel/vm/Configuration.cpp
index 7ddea351bfd..e0e414e5669 100644
--- a/storage/ndb/src/kernel/vm/Configuration.cpp
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp
@@ -286,7 +286,8 @@ Configuration::fetch_configuration(){
   if (globalData.ownId)
     cr.setNodeId(globalData.ownId);
 
-  globalData.ownId = cr.allocNodeId(2 /*retry*/,3 /*delay*/);
+  globalData.ownId = cr.allocNodeId(globalData.ownId ? 10 : 2 /*retry*/,
+                                    3 /*delay*/);
   
   if(globalData.ownId == 0){
     ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, 
diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp
index 22f3d2524a9..08232471474 100644
--- a/storage/ndb/src/mgmapi/mgmapi.cpp
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp
@@ -1874,7 +1874,8 @@ const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz
 
 extern "C"
 int
-ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype)
+ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
+                     int log_event)
 {
   CHECK_HANDLE(handle, 0);
   CHECK_CONNECTED(handle, 0);
@@ -1894,9 +1895,11 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype)
   args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
   if (handle->m_name)
     args.put("name", handle->m_name);
+  args.put("log_event", log_event);
 
   const ParserRow reply[]= {
     MGM_CMD("get nodeid reply", NULL, ""),
+      MGM_ARG("error_code", Int, Optional, "Error code"),
       MGM_ARG("nodeid", Int, Optional, "Error message"),
       MGM_ARG("result", String, Mandatory, "Error message"),
     MGM_END()
@@ -1909,14 +1912,16 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype)
   nodeid= -1;
   do {
     const char * buf;
-    if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
+    if (!prop->get("result", &buf) || strcmp(buf, "Ok") != 0)
+    {
       const char *hostname= ndb_mgm_get_connected_host(handle);
       unsigned port=  ndb_mgm_get_connected_port(handle);
       BaseString err;
+      Uint32 error_code= NDB_MGM_ALLOCID_ERROR;
       err.assfmt("Could not alloc node id at %s port %d: %s",
 		 hostname, port, buf);
-      setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
-	       err.c_str());
+      prop->get("error_code", &error_code);
+      setError(handle, error_code, __LINE__, err.c_str());
       break;
     }
     Uint32 _nodeid;
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index 48094800f9a..aee6d4deeb5 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -503,9 +503,10 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
   if (_ownNodeId == 0) // we did not get node id from other server
   {
     NodeId tmp= m_config_retriever->get_configuration_nodeid();
+    int error_code;
 
     if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
-		       0, 0, error_string)){
+		       0, 0, error_code, error_string)){
       ndbout << "Unable to obtain requested nodeid: "
 	     << error_string.c_str() << endl;
       require(false);
@@ -1113,31 +1114,16 @@ int MgmtSrvr::sendSTOP_REQ(const Vector &node_ids,
       const NFCompleteRep * const rep =
 	CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
 #ifdef VM_TRACE
-      ndbout_c("Node %d fail completed", rep->failedNodeId);
+      ndbout_c("sendSTOP_REQ Node %d fail completed", rep->failedNodeId);
 #endif
+      nodes.clear(rep->failedNodeId); // clear the failed node
+      if (singleUserNodeId == 0)
+        stoppedNodes.set(rep->failedNodeId);
       break;
     }
     case GSN_NODE_FAILREP:{
       const NodeFailRep * const rep =
 	CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
-      NodeBitmask failedNodes;
-      failedNodes.assign(NodeBitmask::Size, rep->theNodes);
-#ifdef VM_TRACE
-      {
-	ndbout << "Failed nodes:";
-	for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
-	  if(failedNodes.get(i))
-	    ndbout << " " << i;
-	ndbout << endl;
-      }
-#endif
-      failedNodes.bitAND(nodes);
-      if (!failedNodes.isclear())
-      {
-	nodes.bitANDC(failedNodes); // clear the failed nodes
-	if (singleUserNodeId == 0)
-	  stoppedNodes.bitOR(failedNodes);
-      }
       break;
     }
     default:
@@ -1258,11 +1244,47 @@ int MgmtSrvr::restartNodes(const Vector &node_ids,
                         abort,
                         false,
                         true,
-                        nostart,
+                        true,
                         initialStart);
+
+  if (ret)
+    return ret;
+
   if (stopCount)
     *stopCount = nodes.count();
-  return ret;
+  
+  // start up the nodes again
+  int waitTime = 12000;
+  NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
+  for (unsigned i = 0; i < node_ids.size(); i++)
+  {
+    NodeId nodeId= node_ids[i];
+    enum ndb_mgm_node_status s;
+    s = NDB_MGM_NODE_STATUS_NO_CONTACT;
+#ifdef VM_TRACE
+    ndbout_c("Waiting for %d not started", nodeId);
+#endif
+    while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0)
+    {
+      Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
+      Uint32 connectCount = 0;
+      bool system;
+      const char *address;
+      status(nodeId, &s, &version, &startPhase, 
+             &system, &dynamicId, &nodeGroup, &connectCount, &address);
+      NdbSleep_MilliSleep(100);  
+      waitTime = (maxTime - NdbTick_CurrentMillisecond());
+    }
+  }
+
+  if (nostart)
+    return 0;
+
+  for (unsigned i = 0; i < node_ids.size(); i++)
+  {
+    int result = start(node_ids[i]);
+  }
+  return 0;
 }
 
 /*
@@ -1991,7 +2013,8 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
 			enum ndb_mgm_node_type type,
 			struct sockaddr *client_addr, 
 			SOCKET_SIZE_TYPE *client_addr_len,
-			BaseString &error_string)
+			int &error_code, BaseString &error_string,
+                        int log_event)
 {
   DBUG_ENTER("MgmtSrvr::alloc_node_id");
   DBUG_PRINT("enter", ("nodeid=%d, type=%d, client_addr=%d",
@@ -2000,6 +2023,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
     if (*nodeId == 0) {
       error_string.appfmt("no-nodeid-checks set in management server.\n"
 			  "node id must be set explicitly in connectstring");
+      error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
       DBUG_RETURN(false);
     }
     DBUG_RETURN(true);
@@ -2024,8 +2048,10 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
 
   if(NdbMutex_Lock(m_configMutex))
   {
+    // should not happen
     error_string.appfmt("unable to lock configuration mutex");
-    return false;
+    error_code = NDB_MGM_ALLOCID_ERROR;
+    DBUG_RETURN(false);
   }
   ndb_mgm_configuration_iterator
     iter(* _config->m_configValues, CFG_SECTION_NODE);
@@ -2096,6 +2122,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
 			  "or specifying unique host names in config file.",
 			  id_found, tmp);
       NdbMutex_Unlock(m_configMutex);
+      error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
       DBUG_RETURN(false);
     }
     if (config_hostname == 0) {
@@ -2104,6 +2131,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
 			  "or specifying unique host names in config file,\n"
 			  "or specifying just one mgmt server in config file.",
 			  tmp);
+      error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
       DBUG_RETURN(false);
     }
     id_found= tmp; // mgmt server matched, check for more matches
@@ -2178,8 +2206,9 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
     
     char tmp_str[128];
     m_reserved_nodes.getText(tmp_str);
-    g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.",
-		       id_found, get_connect_address(id_found), tmp_str);
+    g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, "
+                       "m_reserved_nodes %s.",
+                       id_found, get_connect_address(id_found), tmp_str);
     DBUG_RETURN(true);
   }
 
@@ -2199,26 +2228,48 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
     type_c_string.assfmt("%s(%s)", alias, str);
   }
 
-  if (*nodeId == 0) {
+  if (*nodeId == 0)
+  {
     if (found_matching_id)
+    {
       if (found_matching_type)
+      {
 	if (found_free_node)
+        {
 	  error_string.appfmt("Connection done from wrong host ip %s.",
 			      (client_addr)?
-			        inet_ntoa(((struct sockaddr_in *)
+                              inet_ntoa(((struct sockaddr_in *)
 					 (client_addr))->sin_addr):"");
+          error_code = NDB_MGM_ALLOCID_ERROR;
+        }
 	else
+        {
 	  error_string.appfmt("No free node id found for %s.",
 			      type_string.c_str());
+          error_code = NDB_MGM_ALLOCID_ERROR;
+        }
+      }
       else
+      {
 	error_string.appfmt("No %s node defined in config file.",
 			    type_string.c_str());
+        error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+      }
+    }
     else
+    {
       error_string.append("No nodes defined in config file.");
-  } else {
+      error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+    }
+  }
+  else
+  {
     if (found_matching_id)
+    {
       if (found_matching_type)
-	if (found_free_node) {
+      {
+	if (found_free_node)
+        {
 	  // have to split these into two since inet_ntoa overwrites itself
 	  error_string.appfmt("Connection with id %d done from wrong host ip %s,",
 			      *nodeId, inet_ntoa(((struct sockaddr_in *)
@@ -2226,27 +2277,44 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
 	  error_string.appfmt(" expected %s(%s).", config_hostname,
 			      r_config_addr ?
 			      "lookup failed" : inet_ntoa(config_addr));
-	} else
+          error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+	}
+        else
+        {
 	  error_string.appfmt("Id %d already allocated by another node.",
 			      *nodeId);
+          error_code = NDB_MGM_ALLOCID_ERROR;
+        }
+      }
       else
+      {
 	error_string.appfmt("Id %d configured as %s, connect attempted as %s.",
 			    *nodeId, type_c_string.c_str(),
 			    type_string.c_str());
+        error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+      }
+    }
     else
+    {
       error_string.appfmt("No node defined with id=%d in config file.",
 			  *nodeId);
+      error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
+    }
   }
 
-  g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. "
-			"Returned error string \"%s\"",
-			*nodeId,
-			client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "",
-			error_string.c_str());
-
-  NodeBitmask connected_nodes2;
-  get_connected_nodes(connected_nodes2);
+  if (log_event || error_code == NDB_MGM_ALLOCID_CONFIG_MISMATCH)
   {
+    g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s."
+                          " Returned error string \"%s\"",
+                          *nodeId,
+                          client_addr != 0
+                          ? inet_ntoa(((struct sockaddr_in *)
+                                       (client_addr))->sin_addr)
+                          : "",
+                          error_string.c_str());
+
+    NodeBitmask connected_nodes2;
+    get_connected_nodes(connected_nodes2);
     BaseString tmp_connected, tmp_not_connected;
     for(Uint32 i = 0; i < MAX_NODES; i++)
     {
@@ -2473,6 +2541,8 @@ MgmtSrvr::abortBackup(Uint32 backupId)
 MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
   : m_mgmsrv(m)
 {
+  m_reserved_nodes.clear();
+  m_alloc_timeout= 0;
 }
 
 MgmtSrvr::Allocated_resources::~Allocated_resources()
@@ -2491,9 +2561,22 @@ MgmtSrvr::Allocated_resources::~Allocated_resources()
 }
 
 void
-MgmtSrvr::Allocated_resources::reserve_node(NodeId id)
+MgmtSrvr::Allocated_resources::reserve_node(NodeId id, NDB_TICKS timeout)
 {
   m_reserved_nodes.set(id);
+  m_alloc_timeout= NdbTick_CurrentMillisecond() + timeout;
+}
+
+bool
+MgmtSrvr::Allocated_resources::is_timed_out(NDB_TICKS tick)
+{
+  if (m_alloc_timeout && tick > m_alloc_timeout)
+  {
+    g_eventLogger.info("Mgmt server state: nodeid %d timed out.",
+                       get_nodeid());
+    return true;
+  }
+  return false;
 }
 
 NodeId
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
index ddd5247b446..63134991ffe 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -106,7 +106,8 @@ public:
     ~Allocated_resources();
     // methods to reserve/allocate resources which
     // will be freed when running destructor
-    void reserve_node(NodeId id);
+    void reserve_node(NodeId id, NDB_TICKS timeout);
+    bool is_timed_out(NDB_TICKS tick);
     bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId); }
     bool is_reserved(NodeBitmask mask) { return !mask.bitAND(m_reserved_nodes).isclear(); }
     bool isclear() { return m_reserved_nodes.isclear(); }
@@ -114,6 +115,7 @@ public:
   private:
     MgmtSrvr &m_mgmsrv;
     NodeBitmask m_reserved_nodes;
+    NDB_TICKS m_alloc_timeout;
   };
   NdbMutex *m_node_id_mutex;
 
@@ -427,8 +429,10 @@ public:
    */
   bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
   bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type,
-		     struct sockaddr *client_addr, SOCKET_SIZE_TYPE *client_addr_len,
-		     BaseString &error_string);
+		     struct sockaddr *client_addr,
+                     SOCKET_SIZE_TYPE *client_addr_len,
+		     int &error_code, BaseString &error_string,
+                     int log_event = 1);
   
   /**
    *
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index 7b17cfa21e2..be15484688b 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -137,6 +137,8 @@ ParserRow commands[] = {
     MGM_ARG("public key", String, Mandatory, "Public key"),
     MGM_ARG("endian", String, Optional, "Endianness"),
     MGM_ARG("name", String, Optional, "Name of connection"),
+    MGM_ARG("timeout", Int, Optional, "Timeout in seconds"),
+    MGM_ARG("log_event", Int, Optional, "Log failure in cluster log"),
 
   MGM_CMD("get version", &MgmApiSession::getVersion, ""),
   
@@ -259,6 +261,15 @@ ParserRow commands[] = {
   MGM_END()
 };
 
+struct PurgeStruct
+{
+  NodeBitmask free_nodes;/* free nodes as reported
+			  * by ndbd in apiRegReqConf
+			  */
+  BaseString *str;
+  NDB_TICKS tick;
+};
+
 MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock)
   : SocketServer::Session(sock), m_mgmsrv(mgm)
 {
@@ -408,12 +419,15 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
 {
   const char *cmd= "get nodeid reply";
   Uint32 version, nodeid= 0, nodetype= 0xff;
+  Uint32 timeout= 20;  // default seconds timeout
   const char * transporter;
   const char * user;
   const char * password;
   const char * public_key;
   const char * endian= NULL;
   const char * name= NULL;
+  Uint32 log_event= 1;
+  bool log_event_version;
   union { long l; char c[sizeof(long)]; } endian_check;
 
   args.get("version", &version);
@@ -425,6 +439,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
   args.get("public key", &public_key);
   args.get("endian", &endian);
   args.get("name", &name);
+  args.get("timeout", &timeout);
+  /* for backwards compatability keep track if client uses new protocol */
+  log_event_version= args.get("log_event", &log_event);
 
   endian_check.l = 1;
   if(endian 
@@ -464,14 +481,39 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
   NodeId tmp= nodeid;
   if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
     BaseString error_string;
-    if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, 
-				(struct sockaddr*)&addr, &addrlen, error_string)){
+    int error_code;
+    NDB_TICKS tick= 0;
+    /* only report error on second attempt as not to clog the cluster log */
+    while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, 
+                                   (struct sockaddr*)&addr, &addrlen,
+                                   error_code, error_string,
+                                   tick == 0 ? 0 : log_event))
+    {
+      /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
+      if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH)
+      {
+        // attempt to free any timed out reservations
+        tick= NdbTick_CurrentMillisecond();
+        struct PurgeStruct ps;
+        m_mgmsrv.get_connected_nodes(ps.free_nodes);
+        // invert connected_nodes to get free nodes
+        ps.free_nodes.bitXORC(NodeBitmask());
+        ps.str= 0;
+        ps.tick= tick;
+        m_mgmsrv.get_socket_server()->
+          foreachSession(stop_session_if_timed_out,&ps);
+        error_string = "";
+        continue;
+      }
       const char *alias;
       const char *str;
       alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
 						nodetype, &str);
       m_output->println(cmd);
       m_output->println("result: %s", error_string.c_str());
+      /* only use error_code protocol if client knows about it */
+      if (log_event_version)
+        m_output->println("error_code: %d", error_code);
       m_output->println("");
       return;
     }
@@ -491,7 +533,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
   m_output->println("nodeid: %u", tmp);
   m_output->println("result: Ok");
   m_output->println("");
-  m_allocated_resources->reserve_node(tmp);
+  m_allocated_resources->reserve_node(tmp, timeout*1000);
   
   if (name)
     g_eventLogger.info("Node %d: %s", tmp, name);
@@ -1480,14 +1522,6 @@ done:
   m_output->println("");
 }
 
-struct PurgeStruct
-{
-  NodeBitmask free_nodes;/* free nodes as reported
-			  * by ndbd in apiRegReqConf
-			  */
-  BaseString *str;
-};
-
 void
 MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *data)
 {
@@ -1495,7 +1529,20 @@ MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *da
   struct PurgeStruct &ps= *(struct PurgeStruct *)data;
   if (s->m_allocated_resources->is_reserved(ps.free_nodes))
   {
-    ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid());
+    if (ps.str)
+      ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid());
+    s->stopSession();
+  }
+}
+
+void
+MgmApiSession::stop_session_if_timed_out(SocketServer::Session *_s, void *data)
+{
+  MgmApiSession *s= (MgmApiSession *)_s;
+  struct PurgeStruct &ps= *(struct PurgeStruct *)data;
+  if (s->m_allocated_resources->is_reserved(ps.free_nodes) &&
+      s->m_allocated_resources->is_timed_out(ps.tick))
+  {
     s->stopSession();
   }
 }
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
index f97223750a1..975202b96df 100644
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ b/storage/ndb/src/mgmsrv/Services.hpp
@@ -30,6 +30,7 @@
 
 class MgmApiSession : public SocketServer::Session
 {
+  static void stop_session_if_timed_out(SocketServer::Session *_s, void *data);
   static void stop_session_if_not_connected(SocketServer::Session *_s, void *data);
 private:
   typedef Parser Parser_t;
diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp
index fc276472c48..43913d6c5be 100644
--- a/storage/ndb/src/ndbapi/DictCache.cpp
+++ b/storage/ndb/src/ndbapi/DictCache.cpp
@@ -63,6 +63,7 @@ LocalDictCache::~LocalDictCache(){
 
 Ndb_local_table_info * 
 LocalDictCache::get(const char * name){
+  ASSERT_NOT_MYSQLD;
   assert(! is_ndb_blob_table(name));
   const Uint32 len = strlen(name);
   return m_tableHash.getData(name, len);
@@ -70,6 +71,7 @@ LocalDictCache::get(const char * name){
 
 void 
 LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){
+  ASSERT_NOT_MYSQLD;
   assert(! is_ndb_blob_table(name));
   const Uint32 id = tab_info->m_table_impl->m_id;
   m_tableHash.insertKey(name, strlen(name), id, tab_info);
@@ -77,6 +79,7 @@ LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){
 
 void
 LocalDictCache::drop(const char * name){
+  ASSERT_NOT_MYSQLD;
   assert(! is_ndb_blob_table(name));
   Ndb_local_table_info *info= m_tableHash.deleteKey(name, strlen(name));
   DBUG_ASSERT(info != 0);
@@ -100,8 +103,15 @@ GlobalDictCache::~GlobalDictCache(){
     Vector * vers = curr->theData;
     const unsigned sz = vers->size();
     for(unsigned i = 0; im_internalName.c_str()));
 	delete (* vers)[i].m_impl;
+      }
     }
     delete curr->theData;
     curr->theData= NULL;
@@ -164,11 +174,18 @@ GlobalDictCache::get(const char * name)
     TableVersion * ver = & versions->back();
     switch(ver->m_status){
     case OK:
+      if (ver->m_impl->m_status == NdbDictionary::Object::Invalid)
+      {
+        ver->m_status = DROPPED;
+        retreive = true; // Break loop
+        break;
+      }
       ver->m_refCount++;
-      DBUG_PRINT("info", ("Table OK version=%x.%x refCount=%u",
-                           ver->m_impl->m_version & 0xFFFFFF,
-                           ver->m_impl->m_version >> 24,
-                           ver->m_refCount));
+      DBUG_PRINT("info", ("Table OK tab: %p  version=%x.%x refCount=%u",
+                          ver->m_impl,
+                          ver->m_impl->m_version & 0xFFFFFF,
+                          ver->m_impl->m_version >> 24,
+                          ver->m_refCount));
       DBUG_RETURN(ver->m_impl);
     case DROPPED:
       retreive = true; // Break loop
@@ -197,8 +214,8 @@ NdbTableImpl *
 GlobalDictCache::put(const char * name, NdbTableImpl * tab)
 {
   DBUG_ENTER("GlobalDictCache::put");
-  DBUG_PRINT("enter", ("name: %s, internal_name: %s version: %x.%x",
-                       name,
+  DBUG_PRINT("enter", ("tab: %p  name: %s, internal_name: %s version: %x.%x",
+                       tab, name,
                        tab ? tab->m_internalName.c_str() : "tab NULL",
                        tab ? tab->m_version & 0xFFFFFF : 0,
                        tab ? tab->m_version >> 24 : 0));
@@ -264,66 +281,11 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab)
 } 
 
 void
-GlobalDictCache::drop(NdbTableImpl * tab)
-{
-  DBUG_ENTER("GlobalDictCache::drop");
-  DBUG_PRINT("enter", ("internal_name: %s", tab->m_internalName.c_str()));
-  assert(! is_ndb_blob_table(tab));
-
-  unsigned i;
-  const Uint32 len = strlen(tab->m_internalName.c_str());
-  Vector * vers = 
-    m_tableHash.getData(tab->m_internalName.c_str(), len);
-  if(vers == 0){
-    // Should always tried to retreive it first 
-    // and thus there should be a record
-    abort(); 
-  }
-
-  const Uint32 sz = vers->size();
-  if(sz == 0){
-    // Should always tried to retreive it first 
-    // and thus there should be a record
-    abort(); 
-  }
-
-  for(i = 0; i < sz; i++){
-    TableVersion & ver = (* vers)[i];
-    if(ver.m_impl == tab){
-      if(ver.m_refCount == 0 || ver.m_status == RETREIVING ||
-	 ver.m_version != tab->m_version){
-	DBUG_PRINT("info", ("Dropping with refCount=%d status=%d impl=%p",
-                            ver.m_refCount, ver.m_status, ver.m_impl));
-	break;
-      }
-      DBUG_PRINT("info", ("Found table to drop, i: %d, name: %s",
-                          i, ver.m_impl->m_internalName.c_str()));
-      ver.m_refCount--;
-      ver.m_status = DROPPED;
-      if(ver.m_refCount == 0){
-        DBUG_PRINT("info", ("refCount is zero, deleting m_impl"));
-	delete ver.m_impl;
-	vers->erase(i);
-      }
-      DBUG_VOID_RETURN;
-    }
-  }
-
-  for(i = 0; im_internalName.c_str()));
+  DBUG_PRINT("enter", ("tab: %p  internal_name: %s",
+                       tab, tab->m_internalName.c_str()));
   assert(! is_ndb_blob_table(tab));
 
   unsigned i;
@@ -354,6 +316,17 @@ GlobalDictCache::release(NdbTableImpl * tab)
       }
       
       ver.m_refCount--;
+      if (ver.m_impl->m_status == NdbDictionary::Object::Invalid || invalidate)
+      {
+        ver.m_impl->m_status = NdbDictionary::Object::Invalid;
+        ver.m_status = DROPPED;
+      }
+      if (ver.m_refCount == 0 && ver.m_status == DROPPED)
+      {
+        DBUG_PRINT("info", ("refCount is zero, deleting m_impl"));
+        delete ver.m_impl;
+        vers->erase(i);
+      }
       DBUG_VOID_RETURN;
     }
   }
@@ -374,6 +347,7 @@ GlobalDictCache::alter_table_rep(const char * name,
 				 Uint32 tableVersion,
 				 bool altered)
 {
+  DBUG_ENTER("GlobalDictCache::alter_table_rep");
   assert(! is_ndb_blob_table(name));
   const Uint32 len = strlen(name);
   Vector * vers = 
@@ -381,13 +355,13 @@ GlobalDictCache::alter_table_rep(const char * name,
   
   if(vers == 0)
   {
-    return;
+    DBUG_VOID_RETURN;
   }
 
   const Uint32 sz = vers->size();
   if(sz == 0)
   {
-    return;
+    DBUG_VOID_RETURN;
   }
   
   for(Uint32 i = 0; i < sz; i++)
@@ -399,15 +373,16 @@ GlobalDictCache::alter_table_rep(const char * name,
       ver.m_status = DROPPED;
       ver.m_impl->m_status = altered ? 
 	NdbDictionary::Object::Altered : NdbDictionary::Object::Invalid;
-      return;
+      DBUG_VOID_RETURN;
     }
 
     if(i == sz - 1 && ver.m_status == RETREIVING)
     {
       ver.m_impl = altered ? &f_altered_table : &f_invalid_table;
-      return;
+      DBUG_VOID_RETURN;
     } 
   }
+  DBUG_VOID_RETURN;
 }
 
 template class Vector;
diff --git a/storage/ndb/src/ndbapi/DictCache.hpp b/storage/ndb/src/ndbapi/DictCache.hpp
index 2df6a139542..f134e6b348e 100644
--- a/storage/ndb/src/ndbapi/DictCache.hpp
+++ b/storage/ndb/src/ndbapi/DictCache.hpp
@@ -63,11 +63,11 @@ public:
   GlobalDictCache();
   ~GlobalDictCache();
   
+  NdbTableImpl * get(NdbTableImpl *tab);
   NdbTableImpl * get(const char * name);
   
   NdbTableImpl* put(const char * name, NdbTableImpl *);
-  void drop(NdbTableImpl *);
-  void release(NdbTableImpl *);
+  void release(NdbTableImpl *, int invalidate = 0);
 
   void alter_table_rep(const char * name, 
 		       Uint32 tableId, Uint32 tableVersion, bool altered);
diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp
index ed54b894b64..b963aeeff84 100644
--- a/storage/ndb/src/ndbapi/Ndb.cpp
+++ b/storage/ndb/src/ndbapi/Ndb.cpp
@@ -901,6 +901,27 @@ Ndb::setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase )
     DBUG_RETURN((opTupleIdOnNdb(aTableId, val, 1) == val));
 }
 
+int Ndb::initAutoIncrement()
+{
+  if (m_sys_tab_0)
+    return 0;
+
+  BaseString currentDb(getDatabaseName());
+  BaseString currentSchema(getDatabaseSchemaName());
+
+  setDatabaseName("sys");
+  setDatabaseSchemaName("def");
+
+  m_sys_tab_0 = getDictionary()->getTableGlobal("SYSTAB_0");
+
+  // Restore current name space
+  setDatabaseName(currentDb.c_str());
+  setDatabaseSchemaName(currentSchema.c_str());
+
+
+  return (m_sys_tab_0 == NULL);
+}
+
 Uint64
 Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
 {
@@ -916,19 +937,14 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
 
   CHECK_STATUS_MACRO_ZERO;
 
-  BaseString currentDb(getDatabaseName());
-  BaseString currentSchema(getDatabaseSchemaName());
+  if (initAutoIncrement())
+    goto error_return;
 
-  setDatabaseName("sys");
-  setDatabaseSchemaName("def");
   tConnection = this->startTransaction();
   if (tConnection == NULL)
     goto error_return;
 
-  if (usingFullyQualifiedNames())
-    tOperation = tConnection->getNdbOperation("SYSTAB_0");
-  else
-    tOperation = tConnection->getNdbOperation("sys/def/SYSTAB_0");
+  tOperation = tConnection->getNdbOperation(m_sys_tab_0);
   if (tOperation == NULL)
     goto error_handler;
 
@@ -997,20 +1013,12 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op)
 
   this->closeTransaction(tConnection);
 
-  // Restore current name space
-  setDatabaseName(currentDb.c_str());
-  setDatabaseSchemaName(currentSchema.c_str());
-
   DBUG_RETURN(ret);
 
   error_handler:
     theError.code = tConnection->theError.code;
     this->closeTransaction(tConnection);
   error_return:
-    // Restore current name space
-    setDatabaseName(currentDb.c_str());
-    setDatabaseSchemaName(currentSchema.c_str());
-
   DBUG_PRINT("error", ("ndb=%d con=%d op=%d",
              theError.code,
              tConnection ? tConnection->theError.code : -1,
diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp
index 00f71a2f85b..4e3e13b59bf 100644
--- a/storage/ndb/src/ndbapi/NdbBlob.cpp
+++ b/storage/ndb/src/ndbapi/NdbBlob.cpp
@@ -23,6 +23,7 @@
 #include 
 #include "NdbBlobImpl.hpp"
 #include 
+#include 
 #include 
 
 /*
@@ -392,6 +393,13 @@ NdbBlob::isScanOp()
     theNdbOp->theOperationType == NdbOperation::OpenRangeScanRequest;
 }
 
+inline bool
+NdbBlob::isTakeOverOp()
+{
+  return
+    TcKeyReq::getTakeOverScanFlag(theNdbOp->theScanInfo);
+}
+
 // computations (inline)
 
 inline Uint32
@@ -1527,8 +1535,22 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
     if (isUpdateOp() || isWriteOp() || isDeleteOp()) {
       // add operation before this one to read head+inline
       NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp);
+      /*
+       * If main op is from take over scan lock, the added read is done
+       * as committed read:
+       *
+       * In normal transactional case, the row is locked by us and
+       * committed read returns same as normal read.
+       *
+       * In current TRUNCATE TABLE, the deleting trans is committed in
+       * batches and then restarted with new trans id.  A normal read
+       * would hang on the scan delete lock and then fail.
+       */
+      NdbOperation::LockMode lockMode =
+        ! isTakeOverOp() ?
+          NdbOperation::LM_Read : NdbOperation::LM_CommittedRead;
       if (tOp == NULL ||
-          tOp->readTuple() == -1 ||
+          tOp->readTuple(lockMode) == -1 ||
           setTableKeyValue(tOp) == -1 ||
           getHeadInlineValue(tOp) == -1) {
         setErrorCode(tOp);
diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp
index b0ebf90915f..e844dc3369e 100644
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp
@@ -559,6 +559,11 @@ NdbDictionary::Table::getObjectStatus() const {
   return m_impl.m_status;
 }
 
+void
+NdbDictionary::Table::setStatusInvalid() const {
+  m_impl.m_status = NdbDictionary::Object::Invalid;
+}
+
 int 
 NdbDictionary::Table::getObjectVersion() const {
   return m_impl.m_version;
@@ -1330,6 +1335,11 @@ NdbDictionary::Dictionary::dropTable(Table & t){
   return m_impl.dropTable(NdbTableImpl::getImpl(t));
 }
 
+int
+NdbDictionary::Dictionary::dropTableGlobal(const Table & t){
+  return m_impl.dropTableGlobal(NdbTableImpl::getImpl(t));
+}
+
 int
 NdbDictionary::Dictionary::dropTable(const char * name){
   return m_impl.dropTable(name);
@@ -1340,6 +1350,14 @@ NdbDictionary::Dictionary::alterTable(const Table & t){
   return m_impl.alterTable(NdbTableImpl::getImpl(t));
 }
 
+int
+NdbDictionary::Dictionary::alterTableGlobal(const Table & f,
+                                            const Table & t)
+{
+  return m_impl.alterTableGlobal(NdbTableImpl::getImpl(f),
+                                 NdbTableImpl::getImpl(t));
+}
+
 const NdbDictionary::Table * 
 NdbDictionary::Dictionary::getTable(const char * name, void **data) const
 {
@@ -1349,6 +1367,40 @@ NdbDictionary::Dictionary::getTable(const char * name, void **data) const
   return 0;
 }
 
+const NdbDictionary::Index * 
+NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
+                                          const Table &ndbtab) const
+{
+  NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
+                                           NdbTableImpl::getImpl(ndbtab));
+  if(i)
+    return i->m_facade;
+  return 0;
+}
+
+const NdbDictionary::Table * 
+NdbDictionary::Dictionary::getTableGlobal(const char * name) const
+{
+  NdbTableImpl * t = m_impl.getTableGlobal(name);
+  if(t)
+    return t->m_facade;
+  return 0;
+}
+
+int
+NdbDictionary::Dictionary::removeIndexGlobal(const Index &ndbidx,
+                                             int invalidate) const
+{
+  return m_impl.releaseIndexGlobal(NdbIndexImpl::getImpl(ndbidx), invalidate);
+}
+
+int
+NdbDictionary::Dictionary::removeTableGlobal(const Table &ndbtab,
+                                             int invalidate) const
+{
+  return m_impl.releaseTableGlobal(NdbTableImpl::getImpl(ndbtab), invalidate);
+}
+
 void NdbDictionary::Dictionary::putTable(const NdbDictionary::Table * table)
 {
  NdbDictionary::Table  *copy_table = new NdbDictionary::Table;
@@ -1420,6 +1472,13 @@ NdbDictionary::Dictionary::createIndex(const Index & ind)
   return m_impl.createIndex(NdbIndexImpl::getImpl(ind));
 }
 
+int
+NdbDictionary::Dictionary::createIndex(const Index & ind, const Table & tab)
+{
+  return m_impl.createIndex(NdbIndexImpl::getImpl(ind),
+                            NdbTableImpl::getImpl(tab));
+}
+
 int 
 NdbDictionary::Dictionary::dropIndex(const char * indexName,
 				     const char * tableName)
@@ -1427,6 +1486,12 @@ NdbDictionary::Dictionary::dropIndex(const char * indexName,
   return m_impl.dropIndex(indexName, tableName);
 }
 
+int 
+NdbDictionary::Dictionary::dropIndexGlobal(const Index &ind)
+{
+  return m_impl.dropIndexGlobal(NdbIndexImpl::getImpl(ind));
+}
+
 const NdbDictionary::Index * 
 NdbDictionary::Dictionary::getIndex(const char * indexName,
 				    const char * tableName) const
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index cae7488819e..8eb0b37120d 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -50,7 +50,14 @@
 
 #define DICT_WAITFOR_TIMEOUT (7*24*60*60*1000)
 
+#define ERR_RETURN(a,b) \
+{\
+   DBUG_PRINT("exit", ("error %d", (a).code));\
+   DBUG_RETURN(b);\
+}
+
 extern Uint64 g_latest_trans_gci;
+int ndb_dictionary_is_mysqld = 0;
 
 bool
 is_ndb_blob_table(const char* name, Uint32* ptab_id, Uint32* pcol_no)
@@ -1015,7 +1022,7 @@ NdbTableImpl::get_nodes(Uint32 hashValue, const Uint16 ** nodes) const
  */
 
 NdbIndexImpl::NdbIndexImpl() : 
-  NdbDictionary::Index(* this), 
+  NdbDictionary::Index(* this),
   NdbDictObjectImpl(NdbDictionary::Object::OrderedIndex), m_facade(this)
 {
   init();
@@ -1288,44 +1295,30 @@ NdbDictionaryImpl::~NdbDictionaryImpl()
   }
 }
 
-Ndb_local_table_info *
-NdbDictionaryImpl::fetchGlobalTableImpl(const BaseString& internalTableName)
+NdbTableImpl *
+NdbDictionaryImpl::fetchGlobalTableImplRef(const GlobalCacheInitObject &obj)
 {
+  DBUG_ENTER("fetchGlobalTableImplRef");
   NdbTableImpl *impl;
 
   m_globalHash->lock();
-  impl = m_globalHash->get(internalTableName.c_str());
+  impl = m_globalHash->get(obj.m_name.c_str());
   m_globalHash->unlock();
 
   if (impl == 0){
-    impl = m_receiver.getTable(internalTableName,
+    impl = m_receiver.getTable(obj.m_name.c_str(),
 			       m_ndb.usingFullyQualifiedNames());
-    if (impl != 0) {
-      int ret = getBlobTables(*impl);
-      if (ret != 0) {
-        delete impl;
-        impl = 0;
-      }
+    if (impl != 0 && obj.init(*impl))
+    {
+      delete impl;
+      impl = 0;
     }
-
     m_globalHash->lock();
-    m_globalHash->put(internalTableName.c_str(), impl);
+    m_globalHash->put(obj.m_name.c_str(), impl);
     m_globalHash->unlock();
-    
-    if(impl == 0){
-      return 0;
-    }
   }
 
-  Ndb_local_table_info *info=
-    Ndb_local_table_info::create(impl, m_local_table_data_size);
-
-  m_localHash.put(internalTableName.c_str(), info);
-
-  m_ndb.theFirstTupleId[impl->getTableId()] = ~0;
-  m_ndb.theLastTupleId[impl->getTableId()]  = ~0;
-  
-  return info;
+  DBUG_RETURN(impl);
 }
 
 void
@@ -2276,18 +2269,30 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
   }
 
   // Alter the table
-  int ret = m_receiver.alterTable(m_ndb, impl);
-  if(ret == 0){
-    // Remove cached information and let it be refreshed at next access
+  int ret = alterTableGlobal(*local->m_table_impl, impl);
+  if(ret == 0)
+  {
     m_globalHash->lock();
-    local->m_table_impl->m_status = NdbDictionary::Object::Invalid;
-    m_globalHash->drop(local->m_table_impl);
+    m_globalHash->release(local->m_table_impl, 1);
     m_globalHash->unlock();
     m_localHash.drop(originalInternalName);
   }
   DBUG_RETURN(ret);
 }
 
+int NdbDictionaryImpl::alterTableGlobal(NdbTableImpl &old_impl,
+                                        NdbTableImpl &impl)
+{
+  DBUG_ENTER("NdbDictionaryImpl::alterTableGlobal");
+  // Alter the table
+  int ret = m_receiver.alterTable(m_ndb, impl);
+  old_impl.m_status = NdbDictionary::Object::Invalid;
+  if(ret == 0){
+    DBUG_RETURN(ret);
+  }
+  ERR_RETURN(getNdbError(), ret);
+}
+
 int 
 NdbDictInterface::alterTable(Ndb & ndb,
 			      NdbTableImpl & impl)
@@ -2731,6 +2736,7 @@ NdbDictionaryImpl::dropTable(const char * name)
 {
   DBUG_ENTER("NdbDictionaryImpl::dropTable");
   DBUG_PRINT("enter",("name: %s", name));
+  ASSERT_NOT_MYSQLD;
   NdbTableImpl * tab = getTable(name);
   if(tab == 0){
     DBUG_RETURN(-1);
@@ -2743,8 +2749,7 @@ NdbDictionaryImpl::dropTable(const char * name)
     DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName.c_str()));
     m_localHash.drop(internalTableName.c_str());
     m_globalHash->lock();
-    tab->m_status = NdbDictionary::Object::Invalid;
-    m_globalHash->drop(tab);
+    m_globalHash->release(tab, 1);
     m_globalHash->unlock();
     DBUG_RETURN(dropTable(name));
   }
@@ -2792,8 +2797,7 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
     
     m_localHash.drop(internalTableName);
     m_globalHash->lock();
-    impl.m_status = NdbDictionary::Object::Invalid;
-    m_globalHash->drop(&impl);
+    m_globalHash->release(&impl, 1);
     m_globalHash->unlock();
 
     return 0;
@@ -2802,6 +2806,50 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
   return ret;
 }
 
+int
+NdbDictionaryImpl::dropTableGlobal(NdbTableImpl & impl)
+{
+  int res;
+  const char * name = impl.getName();
+  DBUG_ENTER("NdbDictionaryImpl::dropTableGlobal");
+  DBUG_ASSERT(impl.m_status != NdbDictionary::Object::New);
+  DBUG_ASSERT(impl.m_indexType == NdbDictionary::Object::TypeUndefined);
+
+  List list;
+  if ((res = listIndexes(list, impl.m_id)) == -1){
+    ERR_RETURN(getNdbError(), -1);
+  }
+  for (unsigned i = 0; i < list.count; i++) {
+    const List::Element& element = list.elements[i];
+    NdbIndexImpl *idx= getIndexGlobal(element.name, impl);
+    if (idx == NULL)
+    {
+      ERR_RETURN(getNdbError(), -1);
+    }
+    if ((res = dropIndexGlobal(*idx)) == -1)
+    {
+      releaseIndexGlobal(*idx, 1);
+      ERR_RETURN(getNdbError(), -1);
+    }
+    releaseIndexGlobal(*idx, 1);
+  }
+  
+  if (impl.m_noOfBlobs != 0) {
+    if (dropBlobTables(impl) != 0){
+      ERR_RETURN(getNdbError(), -1);
+    }
+  }
+  
+  int ret = m_receiver.dropTable(impl);  
+  impl.m_status = NdbDictionary::Object::Invalid;
+  if(ret == 0 || m_error.code == 709 || m_error.code == 723)
+  {
+    DBUG_RETURN(0);
+  }
+  
+  ERR_RETURN(getNdbError(), ret);
+}
+
 int
 NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
 {
@@ -2822,7 +2870,7 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
       DBUG_PRINT("info", ("col %s: blob table %s: error %d",
                  c.m_name.c_str(), bt->m_internalName.c_str(), m_error.code));
       if (! (ret == 709 || ret == 723)) // "force" mode on
-        DBUG_RETURN(-1);
+        ERR_RETURN(getNdbError(), -1);
     }
     // leave c.m_blobTable defined
   }
@@ -2891,8 +2939,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
 
   m_localHash.drop(internalTableName);
   m_globalHash->lock();
-  impl.m_status = NdbDictionary::Object::Invalid;
-  m_globalHash->drop(&impl);
+  m_globalHash->release(&impl, 1);
   m_globalHash->unlock();
   DBUG_RETURN(0);
 }
@@ -2918,6 +2965,7 @@ NdbIndexImpl*
 NdbDictionaryImpl::getIndexImpl(const char * externalName,
 				const BaseString& internalName)
 {
+  ASSERT_NOT_MYSQLD;
   Ndb_local_table_info * info = get_local_table_info(internalName);
   if(info == 0){
     m_error.code = 4243;
@@ -2938,26 +2986,41 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName,
     return 0;
   }
 
+  return getIndexImpl(externalName, internalName, *tab, *prim);
+}
+
+NdbIndexImpl*
+NdbDictionaryImpl::getIndexImpl(const char * externalName,
+                                const BaseString& internalName,
+				NdbTableImpl &tab,
+                                NdbTableImpl &prim)
+{
+  DBUG_ENTER("NdbDictionaryImpl::getIndexImpl");
+  DBUG_ASSERT(tab.m_indexType != NdbDictionary::Object::TypeUndefined);
   /**
    * Create index impl
    */
   NdbIndexImpl* idx;
-  if(NdbDictInterface::create_index_obj_from_table(&idx, tab, prim) == 0){
-    idx->m_table = tab;
+  if(NdbDictInterface::create_index_obj_from_table(&idx, &tab, &prim) == 0){
+    idx->m_table = &tab;
     idx->m_externalName.assign(externalName);
     idx->m_internalName.assign(internalName);
+    idx->m_table_id = prim.getObjectId();
+      idx->m_table_version = prim.getObjectVersion();
     // TODO Assign idx to tab->m_index
     // Don't do it right now since assign can't asign a table with index
     // tab->m_index = idx;
-    return idx;
+    DBUG_RETURN(idx);
   }
-  return 0;
+  DBUG_RETURN(0);
 }
 
 int
 NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
 					      NdbTableImpl* tab,
-					      const NdbTableImpl* prim){
+					      const NdbTableImpl* prim)
+{
+  DBUG_ENTER("NdbDictInterface::create_index_obj_from_table");
   NdbIndexImpl *idx = new NdbIndexImpl();
   idx->m_version = tab->m_version;
   idx->m_status = tab->m_status;
@@ -3010,8 +3073,8 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
   }
 
   * dst = idx;
-
-  return 0;
+  DBUG_PRINT("exit", ("m_id: %d  m_version: %d", idx->m_id, idx->m_version));
+  DBUG_RETURN(0);
 }
 
 /*****************************************************************
@@ -3020,6 +3083,7 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
 int
 NdbDictionaryImpl::createIndex(NdbIndexImpl &ix)
 {
+  ASSERT_NOT_MYSQLD;
   NdbTableImpl* tab = getTable(ix.getTable());
   if(tab == 0){
     m_error.code = 4249;
@@ -3029,6 +3093,12 @@ NdbDictionaryImpl::createIndex(NdbIndexImpl &ix)
   return m_receiver.createIndex(m_ndb, ix, * tab);
 }
 
+int
+NdbDictionaryImpl::createIndex(NdbIndexImpl &ix, NdbTableImpl &tab)
+{
+  return m_receiver.createIndex(m_ndb, ix, tab);
+}
+
 int 
 NdbDictInterface::createIndex(Ndb & ndb,
 			      const NdbIndexImpl & impl, 
@@ -3135,6 +3205,7 @@ int
 NdbDictionaryImpl::dropIndex(const char * indexName, 
 			     const char * tableName)
 {
+  ASSERT_NOT_MYSQLD;
   NdbIndexImpl * idx = getIndex(indexName, tableName);
   if (idx == 0) {
     m_error.code = 4243;
@@ -3152,8 +3223,7 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
 
     m_localHash.drop(internalIndexName.c_str());
     m_globalHash->lock();
-    idx->m_table->m_status = NdbDictionary::Object::Invalid;
-    m_globalHash->drop(idx->m_table);
+    m_globalHash->release(idx->m_table, 1);
     m_globalHash->unlock();
     return dropIndex(indexName, tableName);
   }
@@ -3183,13 +3253,13 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
       return dropIndex(indexName, tableName);
     }
 
-    int ret = m_receiver.dropIndex(impl, *timpl);
-    if(ret == 0){
-      m_localHash.drop(internalIndexName.c_str());
+    int ret= dropIndexGlobal(impl);
+    if (ret == 0)
+    {
       m_globalHash->lock();
-      impl.m_table->m_status = NdbDictionary::Object::Invalid;
-      m_globalHash->drop(impl.m_table);
+      m_globalHash->release(impl.m_table, 1);
       m_globalHash->unlock();
+      m_localHash.drop(internalIndexName.c_str());
     }
     return ret;
   }
@@ -3198,10 +3268,26 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
   return -1;
 }
 
+int
+NdbDictionaryImpl::dropIndexGlobal(NdbIndexImpl & impl)
+{
+  DBUG_ENTER("NdbDictionaryImpl::dropIndexGlobal");
+  int ret = m_receiver.dropIndex(impl, *impl.m_table);
+  impl.m_status = NdbDictionary::Object::Invalid;
+  if(ret == 0)
+  {
+    DBUG_RETURN(0);
+  }
+  ERR_RETURN(getNdbError(), ret);
+}
+
 int
 NdbDictInterface::dropIndex(const NdbIndexImpl & impl, 
 			    const NdbTableImpl & timpl)
 {
+  DBUG_ENTER("NdbDictInterface::dropIndex");
+  DBUG_PRINT("enter", ("indexId: %d  indexVersion: %d",
+                       timpl.m_id, timpl.m_version));
   NdbApiSignal tSignal(m_reference);
   tSignal.theReceiversBlockNumber = DBDICT;
   tSignal.theVerId_signalNumber   = GSN_DROP_INDX_REQ;
@@ -3223,9 +3309,9 @@ NdbDictInterface::dropIndex(const NdbIndexImpl & impl,
 		     errCodes);
   if(m_error.code == DropIndxRef::InvalidIndexVersion) {
     // Clear caches and try again
-    return INCOMPATIBLE_VERSION;
+    ERR_RETURN(m_error, INCOMPATIBLE_VERSION);
   }
-  return r;
+  ERR_RETURN(m_error, r);
 }
 
 void
@@ -3262,7 +3348,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
     if(tab == 0){
       DBUG_PRINT("info",("NdbDictionaryImpl::createEvent: table not found: %s",
 			 evnt.getTableName()));
-      DBUG_RETURN(-1);
+      ERR_RETURN(getNdbError(), -1);
     }
     evnt.setTable(tab);
   }
@@ -3281,7 +3367,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
       ndbout_c("Attr id %u in table %s not found", evnt.m_attrIds[i],
 	       evnt.getTableName());
       m_error.code= 4713;
-      DBUG_RETURN(-1);
+      ERR_RETURN(getNdbError(), -1);
     }
   }
 
@@ -3302,7 +3388,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
       table.getColumn(evnt.m_columns[i]->m_name.c_str());
     if(col == 0){
       m_error.code= 4247;
-      DBUG_RETURN(-1);
+      ERR_RETURN(getNdbError(), -1);
     }
     // Copy column definition
     *evnt.m_columns[i] = *col;
@@ -3328,7 +3414,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
   for(i = 1; im_attrId == evnt.m_columns[i]->m_attrId) {
       m_error.code= 4258;
-      DBUG_RETURN(-1);
+      ERR_RETURN(getNdbError(), -1);
     }
   }
   
@@ -3340,14 +3426,14 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
 
   // NdbDictInterface m_receiver;
   if (m_receiver.createEvent(m_ndb, evnt, 0 /* getFlag unset */) != 0)
-    DBUG_RETURN(-1);
+    ERR_RETURN(getNdbError(), -1);
 
   // Create blob events
   if (evnt.m_mergeEvents && createBlobEvents(evnt) != 0) {
     int save_code = m_error.code;
     (void)dropEvent(evnt.m_name.c_str());
     m_error.code = save_code;
-    DBUG_RETURN(-1);
+    ERR_RETURN(getNdbError(), -1);
   }
   DBUG_RETURN(0);
 }
@@ -3367,7 +3453,7 @@ NdbDictionaryImpl::createBlobEvents(NdbEventImpl& evnt)
     NdbEventImpl blob_evnt;
     NdbBlob::getBlobEvent(blob_evnt, &evnt, &c);
     if (createEvent(blob_evnt) != 0)
-      DBUG_RETURN(-1);
+      ERR_RETURN(getNdbError(), -1);
   }
   DBUG_RETURN(0);
 }
@@ -3418,7 +3504,7 @@ NdbDictInterface::createEvent(class Ndb & ndb,
   const size_t len = strlen(evnt.m_name.c_str()) + 1;
   if(len > MAX_TAB_NAME_SIZE) {
     m_error.code= 4241;
-    DBUG_RETURN(-1);
+    ERR_RETURN(getNdbError(), -1);
   }
 
   w.add(SimpleProperties::StringValue, evnt.m_name.c_str());
@@ -3442,7 +3528,7 @@ NdbDictInterface::createEvent(class Ndb & ndb,
 		       0, -1);
 
   if (ret) {
-    DBUG_RETURN(ret);
+    ERR_RETURN(getNdbError(), ret);
   }
   
   char *dataPtr = (char *)m_buffer.get_data();
@@ -3468,7 +3554,7 @@ NdbDictInterface::createEvent(class Ndb & ndb,
 	//evnt.m_attrListBitmask != evntConf->getAttrListBitmask() ||
 	evnt.mi_type           != evntConf->getEventType()) {
       ndbout_c("ERROR*************");
-      DBUG_RETURN(1);
+      ERR_RETURN(getNdbError(), 1);
     }
   }
 
@@ -3555,7 +3641,7 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
   DBUG_ENTER("NdbDictionaryImpl::getEvent");
   DBUG_PRINT("enter",("eventName= %s", eventName));
 
- NdbEventImpl *ev =  new NdbEventImpl();
+  NdbEventImpl *ev =  new NdbEventImpl();
   if (ev == NULL) {
     DBUG_RETURN(NULL);
   }
@@ -3569,35 +3655,36 @@ NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
     DBUG_RETURN(NULL);
   }
 
-  if (tab == NULL) {
-    // We only have the table name with internal name
-    DBUG_PRINT("info",("table %s", ev->getTableName()));
-    Ndb_local_table_info *info;
-    info= get_local_table_info(ev->getTableName());
-    if (info == 0)
+  // We only have the table name with internal name
+  DBUG_PRINT("info",("table %s", ev->getTableName()));
+  if (tab == NULL)
+  {
+    tab= fetchGlobalTableImplRef(InitTable(this, ev->getTableName()));
+    if (tab == 0)
     {
       DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
       delete ev;
       DBUG_RETURN(NULL);
     }
-    if ((info->m_table_impl->m_status != NdbDictionary::Object::Retrieved) ||
-        (info->m_table_impl->m_id != ev->m_table_id) ||
-        (table_version_major(info->m_table_impl->m_version) !=
+    if ((tab->m_status != NdbDictionary::Object::Retrieved) ||
+        (tab->m_id != ev->m_table_id) ||
+        (table_version_major(tab->m_version) !=
          table_version_major(ev->m_table_version)))
     {
-      removeCachedObject(*info->m_table_impl);
-      info= get_local_table_info(ev->getTableName());
-      if (info == 0)
+      DBUG_PRINT("info", ("mismatch on verison in cache"));
+      releaseTableGlobal(*tab, 1);
+      tab= fetchGlobalTableImplRef(InitTable(this, ev->getTableName()));
+      if (tab == 0)
       {
         DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
         delete ev;
         DBUG_RETURN(NULL);
       }
     }
-    tab = info->m_table_impl;
   }
 
   ev->setTable(tab);
+
   ev->setTable(m_ndb.externalizeTableName(ev->getTableName()));  
   // get the columns from the attrListBitmask
   NdbTableImpl &table = *ev->m_tableImpl;
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index 38033e7237b..5a7a1ebb0ab 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -35,6 +35,9 @@ is_ndb_blob_table(const char* name, Uint32* ptab_id = 0, Uint32* pcol_no = 0);
 bool
 is_ndb_blob_table(const class NdbTableImpl* t);
 
+extern int ndb_dictionary_is_mysqld;
+#define ASSERT_NOT_MYSQLD assert(ndb_dictionary_is_mysqld == 0)
+
 class NdbDictObjectImpl {
 public:
   int m_id;
@@ -253,6 +256,8 @@ public:
   BaseString m_internalName;
   BaseString m_externalName;
   BaseString m_tableName;
+  Uint32 m_table_id;
+  Uint32 m_table_version;
   Vector m_columns;
   Vector m_key_ids;
 
@@ -539,6 +544,21 @@ private:
   UtilBuffer m_buffer;
 };
 
+class NdbDictionaryImpl;
+class GlobalCacheInitObject
+{
+public:
+  NdbDictionaryImpl *m_dict;
+  const BaseString &m_name;
+  GlobalCacheInitObject(NdbDictionaryImpl *dict,
+                        const BaseString &name) :
+    m_dict(dict),
+    m_name(name)
+  {}
+  virtual ~GlobalCacheInitObject() {}
+  virtual int init(NdbTableImpl &tab) const = 0;
+};
+
 class NdbDictionaryImpl : public NdbDictionary::Dictionary {
 public:
   NdbDictionaryImpl(Ndb &ndb);
@@ -558,6 +578,7 @@ public:
   int removeCachedObject(NdbTableImpl &);
 
   int createIndex(NdbIndexImpl &ix);
+  int createIndex(NdbIndexImpl &ix, NdbTableImpl & tab);
   int dropIndex(const char * indexName, 
 		const char * tableName);
   int dropIndex(NdbIndexImpl &, const char * tableName);
@@ -578,6 +599,15 @@ public:
   int listObjects(List& list, NdbDictionary::Object::Type type);
   int listIndexes(List& list, Uint32 indexId);
 
+  NdbTableImpl * getTableGlobal(const char * tableName);
+  NdbIndexImpl * getIndexGlobal(const char * indexName,
+                                NdbTableImpl &ndbtab);
+  int alterTableGlobal(NdbTableImpl &orig_impl, NdbTableImpl &impl);
+  int dropTableGlobal(NdbTableImpl &);
+  int dropIndexGlobal(NdbIndexImpl & impl);
+  int releaseTableGlobal(NdbTableImpl & impl, int invalidate);
+  int releaseIndexGlobal(NdbIndexImpl & impl, int invalidate);
+
   NdbTableImpl * getTable(const char * tableName, void **data= 0);
   NdbTableImpl * getBlobTable(const NdbTableImpl&, uint col_no);
   NdbTableImpl * getBlobTable(uint tab_id, uint col_no);
@@ -616,10 +646,14 @@ public:
   NdbDictInterface m_receiver;
   Ndb & m_ndb;
 
-private:
+  NdbIndexImpl* getIndexImpl(const char * externalName,
+                             const BaseString& internalName,
+                             NdbTableImpl &tab,
+                             NdbTableImpl &prim);
   NdbIndexImpl * getIndexImpl(const char * name,
                               const BaseString& internalName);
-  Ndb_local_table_info * fetchGlobalTableImpl(const BaseString& internalName);
+private:
+  NdbTableImpl * fetchGlobalTableImplRef(const GlobalCacheInitObject &obj);
 };
 
 inline
@@ -852,6 +886,27 @@ NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){
  * Inline:d getters
  */
 
+class InitTable : public GlobalCacheInitObject
+{
+public:
+  InitTable(NdbDictionaryImpl *dict,
+            const BaseString &name) :
+    GlobalCacheInitObject(dict, name)
+  {}
+  int init(NdbTableImpl &tab) const
+  {
+    return m_dict->getBlobTables(tab);
+  }
+};
+
+inline
+NdbTableImpl *
+NdbDictionaryImpl::getTableGlobal(const char * table_name)
+{
+  const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
+  return fetchGlobalTableImplRef(InitTable(this, internal_tabname));
+}
+
 inline
 NdbTableImpl *
 NdbDictionaryImpl::getTable(const char * table_name, void **data)
@@ -885,21 +940,134 @@ NdbDictionaryImpl::get_local_table_info(const BaseString& internalTableName)
   DBUG_PRINT("enter", ("table: %s", internalTableName.c_str()));
 
   Ndb_local_table_info *info= m_localHash.get(internalTableName.c_str());
-  if (info == 0) {
-    info= fetchGlobalTableImpl(internalTableName);
-    if (info == 0) {
-      DBUG_RETURN(0);
+  if (info == 0)
+  {
+    NdbTableImpl *tab=
+      fetchGlobalTableImplRef(InitTable(this, internalTableName));
+    if (tab)
+    {
+      info= Ndb_local_table_info::create(tab, m_local_table_data_size);
+      if (info)
+      {
+        m_localHash.put(internalTableName.c_str(), info);
+        m_ndb.theFirstTupleId[tab->getTableId()] = ~0;
+        m_ndb.theLastTupleId[tab->getTableId()]  = ~0;
+      }
     }
   }
   DBUG_RETURN(info); // autoincrement already initialized
 }
 
+class InitIndexGlobal : public GlobalCacheInitObject
+{
+public:
+  const char *m_index_name;
+  NdbTableImpl &m_prim;
+
+  InitIndexGlobal(NdbDictionaryImpl *dict,
+                  const BaseString &internal_indexname,
+                  const char *index_name,
+            NdbTableImpl &prim) :
+    GlobalCacheInitObject(dict, internal_indexname),
+    m_index_name(index_name),
+    m_prim(prim)
+  {}
+  int init(NdbTableImpl &tab) const
+  {
+    tab.m_index= m_dict->getIndexImpl(m_index_name, m_name, tab, m_prim);
+    if (tab.m_index == 0)
+      return 1;
+    tab.m_index->m_table= &tab;
+    return 0;
+  }
+};
+
+class InitIndex : public GlobalCacheInitObject
+{
+public:
+  const char *m_index_name;
+
+  InitIndex(NdbDictionaryImpl *dict,
+            const BaseString &internal_indexname,
+            const char *index_name) :
+    GlobalCacheInitObject(dict, internal_indexname),
+    m_index_name(index_name)
+  {}
+  int init(NdbTableImpl &tab) const
+  {
+    DBUG_ASSERT(tab.m_index == 0);
+    tab.m_index= m_dict->getIndexImpl(m_index_name, m_name);
+    if (tab.m_index)
+    {
+      tab.m_index->m_table= &tab;
+      return 0;
+    }
+    return 1;
+  }
+};
+
+inline
+NdbIndexImpl * 
+NdbDictionaryImpl::getIndexGlobal(const char * index_name,
+                                  NdbTableImpl &ndbtab)
+{
+  DBUG_ENTER("NdbDictionaryImpl::getIndexGlobal");
+  const BaseString
+    internal_indexname(m_ndb.internalize_index_name(&ndbtab, index_name));
+  int retry= 2;
+
+  while (retry)
+  {
+    NdbTableImpl *tab=
+      fetchGlobalTableImplRef(InitIndexGlobal(this, internal_indexname,
+                                              index_name, ndbtab));
+    if (tab)
+    {
+      // tab->m_index sould be set. otherwise tab == 0
+      NdbIndexImpl *idx= tab->m_index;
+      if (idx->m_table_id != ndbtab.getObjectId() ||
+          idx->m_table_version != ndbtab.getObjectVersion())
+      {
+        releaseIndexGlobal(*idx, 1);
+        retry--;
+        continue;
+      }
+      DBUG_RETURN(idx);
+    }
+    break;
+  }
+  m_error.code= 4243;
+  DBUG_RETURN(0);
+}
+
+inline int
+NdbDictionaryImpl::releaseTableGlobal(NdbTableImpl & impl, int invalidate)
+{
+  DBUG_ENTER("NdbDictionaryImpl::releaseTableGlobal");
+  DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
+  m_globalHash->lock();
+  m_globalHash->release(&impl, invalidate);
+  m_globalHash->unlock();
+  DBUG_RETURN(0);
+}
+
+inline int
+NdbDictionaryImpl::releaseIndexGlobal(NdbIndexImpl & impl, int invalidate)
+{
+  DBUG_ENTER("NdbDictionaryImpl::releaseIndexGlobal");
+  DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
+  m_globalHash->lock();
+  m_globalHash->release(impl.m_table, invalidate);
+  m_globalHash->unlock();
+  DBUG_RETURN(0);
+}
+
 inline
 NdbIndexImpl * 
 NdbDictionaryImpl::getIndex(const char * index_name,
 			    const char * table_name)
 {
-  if (table_name || m_ndb.usingFullyQualifiedNames())
+  while (table_name || m_ndb.usingFullyQualifiedNames())
   {
     const BaseString internal_indexname(
       (table_name)
@@ -910,18 +1078,28 @@ NdbDictionaryImpl::getIndex(const char * index_name,
 
     if (internal_indexname.length())
     {
-      Ndb_local_table_info * info=
-        get_local_table_info(internal_indexname);
-      if (info)
+      Ndb_local_table_info *info= m_localHash.get(internal_indexname.c_str());
+      NdbTableImpl *tab;
+      if (info == 0)
       {
-	NdbTableImpl * tab= info->m_table_impl;
-        if (tab->m_index == 0)
-          tab->m_index= getIndexImpl(index_name, internal_indexname);
-        if (tab->m_index != 0)
-          tab->m_index->m_table= tab;
-        return tab->m_index;
+        tab= fetchGlobalTableImplRef(InitIndex(this, internal_indexname,
+                                               index_name));
+        if (tab)
+        {
+          info= Ndb_local_table_info::create(tab, 0);
+          if (info)
+            m_localHash.put(internal_indexname.c_str(), info);
+          else
+            break;
+        }
+        else
+          break;
       }
+      else
+        tab= info->m_table_impl;
+      return tab->m_index;
     }
+    break;
   }
 
   m_error.code= 4243;
diff --git a/storage/ndb/src/ndbapi/NdbIndexStat.cpp b/storage/ndb/src/ndbapi/NdbIndexStat.cpp
index 8740b80a81d..e490290b6a2 100644
--- a/storage/ndb/src/ndbapi/NdbIndexStat.cpp
+++ b/storage/ndb/src/ndbapi/NdbIndexStat.cpp
@@ -377,7 +377,7 @@ NdbIndexStat::stat_select(const Uint32* key1, Uint32 keylen1, const Uint32* key2
 }
 
 int
-NdbIndexStat::records_in_range(NdbDictionary::Index* index, NdbIndexScanOperation* op, Uint64 table_rows, Uint64* count, int flags)
+NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOperation* op, Uint64 table_rows, Uint64* count, int flags)
 {
   DBUG_ENTER("NdbIndexStat::records_in_range");
   Uint64 rows;
diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp
index b502ec27b9d..e41380e6484 100644
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp
@@ -99,6 +99,7 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
   for (i = 0; i < MAX_NDB_NODES ; i++) {
     theConnectionArray[i] = NULL;
   }//forg
+  m_sys_tab_0 = NULL;
   for (i = 0; i < 2048 ; i++) {
     theFirstTupleId[i] = 0;
     theLastTupleId[i] = 0;
@@ -137,6 +138,9 @@ Ndb::~Ndb()
   DBUG_ENTER("Ndb::~Ndb()");
   DBUG_PRINT("enter",("this=0x%x",this));
 
+  if (m_sys_tab_0)
+    getDictionary()->removeTableGlobal(*m_sys_tab_0, 0);
+
   assert(theImpl->m_ev_op == 0); // user should return NdbEventOperation's
   for (NdbEventOperationImpl *op= theImpl->m_ev_op; op; op=op->m_next)
   {
diff --git a/storage/ndb/test/ndbapi/testBlobs.cpp b/storage/ndb/test/ndbapi/testBlobs.cpp
index a1b0c89652e..bf9a8b1bce9 100644
--- a/storage/ndb/test/ndbapi/testBlobs.cpp
+++ b/storage/ndb/test/ndbapi/testBlobs.cpp
@@ -44,6 +44,7 @@ struct Opt {
   bool m_dbg;
   bool m_dbgall;
   const char* m_dbug;
+  bool m_fac;
   bool m_full;
   unsigned m_loop;
   unsigned m_parts;
@@ -72,6 +73,7 @@ struct Opt {
     m_dbg(false),
     m_dbgall(false),
     m_dbug(0),
+    m_fac(false),
     m_full(false),
     m_loop(1),
     m_parts(10),
@@ -110,6 +112,7 @@ printusage()
     << "  -dbg        print debug" << endl
     << "  -dbgall     print also NDB API debug (if compiled in)" << endl
     << "  -dbug opt   dbug options" << endl
+    << "  -fac        fetch across commit in scan delete [" << d.m_fac << "]" << endl
     << "  -full       read/write only full blob values" << endl
     << "  -loop N     loop N times 0=forever [" << d.m_loop << "]" << endl
     << "  -parts N    max parts in blob value [" << d.m_parts << "]" << endl
@@ -1255,23 +1258,11 @@ deleteScan(bool idx)
       CHK((ret = g_ops->nextResult(false)) == 0 || ret == 1 || ret == 2);
       if (++n == g_opt.m_batch || ret == 2) {
         DBG("execute batch: n=" << n << " ret=" << ret);
-        switch (0) {
-        case 0: // works normally
+        if (! g_opt.m_fac) {
           CHK(g_con->execute(NoCommit) == 0);
-          CHK(true || g_con->restart() == 0);
-          break;
-        case 1: // nonsense - g_con is invalid for 2nd batch
-          CHK(g_con->execute(Commit) == 0);
-          CHK(true || g_con->restart() == 0);
-          break;
-        case 2: // DBTC sendSignalErrorRefuseLab
-          CHK(g_con->execute(NoCommit) == 0);
-          CHK(g_con->restart() == 0);
-          break;
-        case 3: // 266 time-out
+        } else {
           CHK(g_con->execute(Commit) == 0);
           CHK(g_con->restart() == 0);
-          break;
         }
         n = 0;
       }
@@ -1817,6 +1808,10 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
 	continue;
       }
     }
+    if (strcmp(arg, "-fac") == 0) {
+      g_opt.m_fac = true;
+      continue;
+    }
     if (strcmp(arg, "-full") == 0) {
       g_opt.m_full = true;
       continue;
diff --git a/storage/ndb/tools/delete_all.cpp b/storage/ndb/tools/delete_all.cpp
index feedded06ad..fcf9b425bd0 100644
--- a/storage/ndb/tools/delete_all.cpp
+++ b/storage/ndb/tools/delete_all.cpp
@@ -23,17 +23,21 @@
 #include 
 
 static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
-                       bool commit_across_open_cursor, int parallelism=240);
+                       bool fetch_across_commit, int parallelism=240);
 
 NDB_STD_OPTS_VARS;
 
 static const char* _dbname = "TEST_DB";
+static my_bool _transactional = false;
 static struct my_option my_long_options[] =
 {
   NDB_STD_OPTS("ndb_desc"),
   { "database", 'd', "Name of database table is in",
     (gptr*) &_dbname, (gptr*) &_dbname, 0,
     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+  { "transactional", 't', "Single transaction (may run out of operations)",
+    (gptr*) &_transactional, (gptr*) &_transactional, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 static void usage()
@@ -84,18 +88,11 @@ int main(int argc, char** argv){
       ndbout << " Table " << argv[i] << " does not exist!" << endl;
       return NDBT_ProgramExit(NDBT_WRONGARGS);
     }
-    // Check if we have any blobs
-    bool commit_across_open_cursor = true;
-    for (int j = 0; j < pTab->getNoOfColumns(); j++) {
-      NdbDictionary::Column::Type t = pTab->getColumn(j)->getType();
-      if (t == NdbDictionary::Column::Blob ||
-          t == NdbDictionary::Column::Text) {
-        commit_across_open_cursor = false;
-        break;
-      }
-    }
-    ndbout << "Deleting all from " << argv[i] << "...";
-    if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){
+    ndbout << "Deleting all from " << argv[i];
+    if (! _transactional)
+      ndbout << " (non-transactional)";
+    ndbout << " ...";
+    if(clear_table(&MyNdb, pTab, ! _transactional) == NDBT_FAILED){
       res = NDBT_FAILED;
       ndbout << "FAILED" << endl;
     }
@@ -105,7 +102,7 @@ int main(int argc, char** argv){
 
 
 int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
-                bool commit_across_open_cursor, int parallelism)
+                bool fetch_across_commit, int parallelism)
 {
   // Scan all records exclusive and delete 
   // them one by one
@@ -136,7 +133,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
       }
       goto failed;
     }
-    
+
     pOp = pTrans->getNdbScanOperation(pTab->getName());	
     if (pOp == NULL) {
       goto failed;
@@ -167,7 +164,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
       } while((check = pOp->nextResult(false)) == 0);
       
       if(check != -1){
-        if (commit_across_open_cursor) {
+        if (fetch_across_commit) {
           check = pTrans->execute(NdbTransaction::Commit);   
           pTrans->restart(); // new tx id
         } else {
@@ -198,7 +195,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab,
       }
       goto failed;
     }
-    if (! commit_across_open_cursor &&
+    if (! fetch_across_commit &&
         pTrans->execute(NdbTransaction::Commit) != 0) {
       err = pTrans->getNdbError();
       goto failed;
diff --git a/storage/ndb/tools/listTables.cpp b/storage/ndb/tools/listTables.cpp
index ef51b66bb10..a221156280d 100644
--- a/storage/ndb/tools/listTables.cpp
+++ b/storage/ndb/tools/listTables.cpp
@@ -188,6 +188,8 @@ list(const char * tabname,
             ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name);
         }
     }
+    if (_parsable)
+      exit(0);
 }
 
 NDB_STD_OPTS_VARS;
diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt
index f7a10f95880..40f171440a4 100644
--- a/strings/CHARSET_INFO.txt
+++ b/strings/CHARSET_INFO.txt
@@ -172,7 +172,7 @@ mb_wc       - converts the left multibyte sequence into it Unicode code.
 mc_mb       - converts the given Unicode code into multibyte sequence.
 
 
-Case and sort convertion
+Case and sort conversion
 ------------------------
 caseup_str  - converts the given 0-terminated string into the upper case
 casedn_str  - converts the given 0-terminated string into the lower case
@@ -227,4 +227,4 @@ hash_sort()   - calculates hash value taking in account
                 the collation rules, e.g. case-insensitivity, 
                 accent sensitivity, etc.
 
- 
\ No newline at end of file
+ 
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index 0e036c2bbcd..e4302f50c58 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -27,6 +27,7 @@
     %#[l]d
     %#[l]u
     %#[l]x
+    %#.#b 	Local format; note first # is ignored and second is REQUIRED
     %#.#s	Note first # is ignored
     
   RETURN
@@ -40,7 +41,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
 
   for (; *fmt ; fmt++)
   {
-    if (fmt[0] != '%')
+    if (*fmt != '%')
     {
       if (to == end)			/* End of buffer */
 	break;
@@ -95,6 +96,16 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
       to=strnmov(to,par,plen);
       continue;
     }
+    else if (*fmt == 'b')				/* Buffer parameter */
+    {
+      char *par = va_arg(ap, char *);
+      DBUG_ASSERT(to <= end);
+      if (to + abs(width) + 1 > end)
+        width= end - to - 1;  /* sign doesn't matter */
+      memmove(to, par, abs(width));
+      to+= width;
+      continue;
+    }
     else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x')	/* Integer parameter */
     {
       register long larg;
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 781b769b7fc..c57496e6c55 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -388,22 +388,12 @@ install -d $RBR%{_sbindir}
 mv $RBR/%{_libdir}/mysql/*.so* $RBR/%{_libdir}/
 
 # install "mysqld-debug" and "mysqld-max"
-if test -f $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/.libs/mysqld
-then
-  install -m 755 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/.libs/mysqld \
+./libtool --mode=execute install -m 755 \
+                 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/mysqld \
                  $RBR%{_sbindir}/mysqld-debug
-else
-  install -m 755 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/mysqld \
-                 $RBR%{_sbindir}/mysqld-debug
-fi
-if test -f $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-max-%{mysql_version}/sql/.libs/mysqld
-then
-  install -m 755 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-max-%{mysql_version}/sql/.libs/mysqld \
+./libtool --mode=execute install -m 755 \
+                 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-max-%{mysql_version}/sql/mysqld \
                  $RBR%{_sbindir}/mysqld-max
-else
-  install -m 755 $RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-max-%{mysql_version}/sql/mysqld \
-                 $RBR%{_sbindir}/mysqld-max
-fi
 
 # install saved perror binary with NDB support (BUG#13740)
 install -m 755 $MBD/extra/perror $RBR%{_bindir}/perror
@@ -473,9 +463,12 @@ usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
 # owns all database files.
 chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir
 
-# Initiate databases
+# Initiate databases if needed
 %{_bindir}/mysql_install_db --rpm --user=%{mysqld_user}
 
+# Upgrade databases if needed
+%{_bindir}/mysql_upgrade --user=%{mysqld_user}
+
 # Change permissions again to fix any new files.
 chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir
 
@@ -541,6 +534,7 @@ fi
 %doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1*
 %doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1*
 %doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1*
+%doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1*
 %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1*
 %doc %attr(644, root, man) %{_mandir}/man1/mysqlmanager.1*
 %doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1*
@@ -552,30 +546,31 @@ fi
 %ghost %config(noreplace,missingok) %{_sysconfdir}/my.cnf
 %ghost %config(noreplace,missingok) %{_sysconfdir}/mysqlmanager.passwd
 
-%attr(755, root, root) %{_bindir}/myisamchk
+%attr(755, root, root) %{_bindir}/my_print_defaults
 %attr(755, root, root) %{_bindir}/myisam_ftdump
+%attr(755, root, root) %{_bindir}/myisamchk
 %attr(755, root, root) %{_bindir}/myisamlog
 %attr(755, root, root) %{_bindir}/myisampack
-%attr(755, root, root) %{_bindir}/my_print_defaults
-%attr(755, root, root) %{_bindir}/mysqlbug
 %attr(755, root, root) %{_bindir}/mysql_convert_table_format
 %attr(755, root, root) %{_bindir}/mysql_create_system_tables
-%attr(755, root, root) %{_bindir}/mysqld_multi
-%attr(755, root, root) %{_bindir}/mysqld_safe
 %attr(755, root, root) %{_bindir}/mysql_explain_log
 %attr(755, root, root) %{_bindir}/mysql_fix_extensions
 %attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables
-%attr(755, root, root) %{_bindir}/mysqlhotcopy
 %attr(755, root, root) %{_bindir}/mysql_install_db
 %attr(755, root, root) %{_bindir}/mysql_secure_installation
 %attr(755, root, root) %{_bindir}/mysql_setpermission
-%attr(755, root, root) %{_bindir}/mysqltest
 %attr(755, root, root) %{_bindir}/mysql_tzinfo_to_sql
+%attr(755, root, root) %{_bindir}/mysql_upgrade
 %attr(755, root, root) %{_bindir}/mysql_zap
+%attr(755, root, root) %{_bindir}/mysqlbug
+%attr(755, root, root) %{_bindir}/mysqld_multi
+%attr(755, root, root) %{_bindir}/mysqld_safe
+%attr(755, root, root) %{_bindir}/mysqlhotcopy
+%attr(755, root, root) %{_bindir}/mysqltest
 %attr(755, root, root) %{_bindir}/perror
 %attr(755, root, root) %{_bindir}/replace
-%attr(755, root, root) %{_bindir}/resolveip
 %attr(755, root, root) %{_bindir}/resolve_stack_dump
+%attr(755, root, root) %{_bindir}/resolveip
 %attr(755, root, root) %{_bindir}/safe_mysqld
 
 %attr(755, root, root) %{_sbindir}/mysqld
@@ -688,6 +683,14 @@ fi
 # itself - note that they must be ordered by date (important when
 # merging BK trees)
 %changelog 
+* Mon May 01 2006 Kent Boortz 
+
+- Use "./libtool --mode=execute" instead of searching for the
+  executable in current directory and ".libs".
+
+* Fri Apr 28 2006 Kent Boortz 
+
+- Install and run "mysql_upgrade"
 
 * Wed Apr 12 2006 Jim Winstead 
 
@@ -697,7 +700,6 @@ fi
 * Tue Apr 11 2006 Jim Winstead 
 
 - Remove old mysqltestmanager and related programs
-
 * Sat Apr 01 2006 Kent Boortz 
 
 - Set $LDFLAGS from $MYSQL_BUILD_LDFLAGS
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ba0a7ad73d0..4cad3c30bdd 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,7 +43,7 @@ INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include \
 LIBS =			@CLIENT_LIBS@
 LDADD =			@CLIENT_EXTRA_LDFLAGS@ \
                         $(top_builddir)/libmysql/libmysqlclient.la
-mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS)
+mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -L../mysys -lmysys
 mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix)
 insert_test_SOURCES=       insert_test.c $(yassl_dummy_link_fix)
 select_test_SOURCES=       select_test.c $(yassl_dummy_link_fix)
diff --git a/tests/cmakelists.txt b/tests/cmakelists.txt
index c9b0b8735a2..46c42d461f3 100644
--- a/tests/cmakelists.txt
+++ b/tests/cmakelists.txt
@@ -6,4 +6,4 @@ ADD_DEFINITIONS("-DMYSQL_CLIENT")
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 
 ADD_EXECUTABLE(mysql_client_test mysql_client_test.c)
-TARGET_LINK_LIBRARIES(mysql_client_test dbug mysqlclient yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32)
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 5730efced35..d927b27ab37 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14839,6 +14839,73 @@ static void test_bug15613()
   myquery(rc);
   mysql_stmt_close(stmt);
 }
+
+/*
+  Bug#17667: An attacker has the opportunity to bypass query logging.
+*/
+static void test_bug17667()
+{
+  int rc;
+  struct buffer_and_length {
+    const char *buffer;
+    const uint length;
+  } statements[]= {
+    { "drop table if exists bug17667", 29 },
+    { "create table bug17667 (c varchar(20))", 37 },
+    { "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
+    { "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
+    { "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
+    { "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
+    { "drop table bug17667", 19 },
+    { NULL, 0 } };  
+
+  struct buffer_and_length *statement_cursor;
+  FILE *log_file;
+
+  myheader("test_bug17667");
+
+  for (statement_cursor= statements; statement_cursor->buffer != NULL;
+      statement_cursor++) {
+    rc= mysql_real_query(mysql, statement_cursor->buffer,
+        statement_cursor->length);
+    myquery(rc);
+  }
+
+  sleep(1); /* The server may need time to flush the data to the log. */
+  log_file= fopen("var/log/master.log", "r");
+  if (log_file != NULL) {
+
+    for (statement_cursor= statements; statement_cursor->buffer != NULL;
+        statement_cursor++) {
+     char line_buffer[MAX_TEST_QUERY_LENGTH*2]; 
+     /* more than enough room for the query and some marginalia. */
+
+      do {
+        memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
+
+        DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) !=
+            NULL);
+        /* If we reach EOF before finishing the statement list, then we failed. */
+
+      } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
+            statement_cursor->buffer, statement_cursor->length) == NULL);
+    }
+
+    printf("success.  All queries found intact in the log.\n");
+
+  } else {
+    fprintf(stderr, "Could not find the log file, var/log/master.log, so "
+        "test_bug17667 is \ninconclusive.  Run test from the "
+        "mysql-test/mysql-test-run* program \nto set up the correct "
+        "environment for this test.\n\n");
+  }
+
+  if (log_file != NULL)
+    fclose(log_file);
+
+}
+
+
 /*
   Bug#14169: type of group_concat() result changed to blob if tmp_table was used
 */
@@ -15139,6 +15206,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug16144", test_bug16144 },
   { "test_bug15613", test_bug15613 },
   { "test_bug14169", test_bug14169 },
+  { "test_bug17667", test_bug17667 },
   { 0, 0 }
 };
 
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 4ee27f1e491..002874caf58 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -296,7 +296,7 @@ ctor_failure:
   TODO:
        Add option --verify to mysqld to be able to change verification mode
 */
-struct st_VioSSLAcceptorFd*
+struct st_VioSSLAcceptorFd *
 new_VioSSLAcceptorFd(const char *key_file,
 		     const char *cert_file,
 		     const char *ca_file,
@@ -387,4 +387,12 @@ ctor_failure:
   my_free((gptr) ptr,MYF(0));
   DBUG_RETURN(0);
 }
+
+
+void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd)
+{
+  SSL_CTX_free(fd->ssl_context);
+  my_free((gptr) fd, MYF(0));
+}
+
 #endif /* HAVE_OPENSSL */