diff --git a/client/cmakelists.txt b/client/cmakelists.txt
index 9c9e56d9b4346478f3c70dadc32b5f3e3e9c1c9d..5da9189b0ae05f91e40e0df570053be6e6ea1e47 100644
--- a/client/cmakelists.txt
+++ b/client/cmakelists.txt
@@ -48,7 +48,7 @@ ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
                         ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c 
                         ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
 
-ADD_DEPENDENCIES(mysqlclient comp_err)
+ADD_DEPENDENCIES(mysqlclient GenError)
 ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc)
 LINK_DIRECTORIES(${MYSQL_BINARY_DIR}/mysys ${MYSQL_BINARY_DIR}/zlib)
 TARGET_LINK_LIBRARIES(mysql mysqlclient mysys yassl zlib dbug yassl  taocrypt wsock32)
diff --git a/extra/cmakelists.txt b/extra/cmakelists.txt
index 0f7005da079b3c3d4e7eb0973d3813b195fdf27a..50e0f04eb14350969abae75ae1dde1a14f8a8ca7 100644
--- a/extra/cmakelists.txt
+++ b/extra/cmakelists.txt
@@ -16,8 +16,11 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
                     --name_file=${PROJECT_SOURCE_DIR}/include/mysqld_ername.h
                     --state_file=${PROJECT_SOURCE_DIR}/include/sql_state.h
                     --in_file=${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt
-                   MAIN_DEPENDENCY comp_err
-                   DEPENDS ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt)
+                   DEPENDS comp_err ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt)
+
+ADD_CUSTOM_TARGET(GenError
+                  ALL
+                  DEPENDS ${PROJECT_SOURCE_DIR}/include/mysqld_error.h)
 
 ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
 TARGET_LINK_LIBRARIES(my_print_defaults strings mysys dbug taocrypt odbc32 odbccp32 wsock32)
diff --git a/libmysql/cmakelists.txt b/libmysql/cmakelists.txt
index b6e10306f6dedbbc8f5bf7755001205c6ca8b060..cb3453fc222a6bb99382678fd239c7667a7aeb8b 100644
--- a/libmysql/cmakelists.txt
+++ b/libmysql/cmakelists.txt
@@ -45,7 +45,7 @@ ADD_LIBRARY(libmysql MODULE dll.c libmysql.def
                      ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c 
                      ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c 
                      ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
-ADD_DEPENDENCIES(libmysql dbug vio mysys strings comp_err zlib)
+ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib)
 TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32)
 
 # ToDo: We should move the mytest.c program out in libmysql/
diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result
index 0b554f97b9af0dee92aedf2ed9e38c9592a0c06e..f7100f2052439b876e893f58f7c370a4bb861740 100644
--- a/mysql-test/r/events_bugs.result
+++ b/mysql-test/r/events_bugs.result
@@ -1,5 +1,19 @@
 create database if not exists events_test;
 use events_test;
+set @a=3;
+CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5;
+call p_16();
+"Here we used to crash!"
+call p_16();
+ERROR HY000: Event 'e_16' already exists
+call p_16();
+ERROR HY000: Event 'e_16' already exists
+DROP EVENT e_16;
+CALL p_16();
+CALL p_16();
+ERROR HY000: Event 'e_16' already exists
+DROP PROCEDURE p_16;
+DROP EVENT e_16;
 set global event_scheduler=0;
 "Wait a bit to settle down"
 delete from mysql.event;
diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test
index 2d4374dcb412ca0108f662ba8c3cd6b59632d2f7..4214d8483d17112775ec28259be2d5561eb52fa1 100644
--- a/mysql-test/t/events_bugs.test
+++ b/mysql-test/t/events_bugs.test
@@ -1,5 +1,26 @@
 create database if not exists events_test;
 use events_test;
+#
+# START - BUG#16408: Events: crash for an event in a procedure
+#
+set @a=3;
+CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5;
+call p_16();
+--echo "Here we used to crash!"
+--error 1516
+call p_16();
+--error 1516
+call p_16();
+DROP EVENT e_16;
+CALL p_16();
+--error 1516
+CALL p_16();
+DROP PROCEDURE p_16;
+DROP EVENT e_16;
+#
+# END   - BUG#16408: Events: crash for an event in a procedure
+#
+
 #
 # Start - 16407: Events: Changes in sql_mode won't be taken into account
 #
diff --git a/server-tools/instance-manager/cmakelists.txt b/server-tools/instance-manager/cmakelists.txt
index ff6a107716649ce30de02387555cf0b7bd10af30..32f243b43d98c83def901ed760c535a572a240a8 100644
--- a/server-tools/instance-manager/cmakelists.txt
+++ b/server-tools/instance-manager/cmakelists.txt
@@ -12,5 +12,5 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc
                             ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
                             ../../libmysql/errmsg.c)
 
-ADD_DEPENDENCIES(mysqlmanager comp_err)
+ADD_DEPENDENCIES(mysqlmanager GenError)
 TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
diff --git a/sql/cmakelists.txt b/sql/cmakelists.txt
index 89462a018e6ffa920ba0e45dee1a63b9053877b9..2099ef94996ca4f2892fa94683ad080073951a94 100644
--- a/sql/cmakelists.txt
+++ b/sql/cmakelists.txt
@@ -50,7 +50,7 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc discover.
 					  ${PROJECT_SOURCE_DIR}/sql/handlerton.cc
 					  ${PROJECT_SOURCE_DIR}/sql/lex_hash.h)
 TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg innobase mysys yassl zlib dbug yassl taocrypt strings vio regex wsock32)
-ADD_DEPENDENCIES(mysqld comp_err)
+ADD_DEPENDENCIES(mysqld GenError)
 
 # Sql Parser custom command
 ADD_CUSTOM_COMMAND(
diff --git a/sql/event.h b/sql/event.h
index d070f93c57578766017f88145d4a530c2c474ff1..27de8b46e32a7793e023d10d3ba5e597a266271d 100644
--- a/sql/event.h
+++ b/sql/event.h
@@ -40,7 +40,6 @@
 #define EVENT_EXEC_NO_MORE      (1L << 0)
 #define EVENT_NOT_USED          (1L << 1)
 
-
 extern ulong opt_event_executor;
 
 enum enum_event_on_completion
@@ -122,6 +121,39 @@ class Event_timed
   bool free_sphead_on_delete;
   uint flags;//all kind of purposes
 
+  static void *operator new(size_t size)
+  {
+    void *p;
+    DBUG_ENTER("Event_timed::new(size)");
+    p= my_malloc(size, MYF(0));
+    DBUG_PRINT("info", ("alloc_ptr=0x%lx", p));
+    DBUG_RETURN(p);
+  }
+
+  static void *operator new(size_t size, MEM_ROOT *mem_root)
+  { return (void*) alloc_root(mem_root, (uint) size); }
+
+  static void operator delete(void *ptr, size_t size)
+  {
+    DBUG_ENTER("Event_timed::delete(ptr,size)");
+    DBUG_PRINT("enter", ("free_ptr=0x%lx", ptr));
+    TRASH(ptr, size);
+    my_free((gptr) ptr, MYF(0));
+    DBUG_VOID_RETURN;
+  }
+
+  static void operator delete(void *ptr, MEM_ROOT *mem_root)
+  {
+    /*
+      Don't free the memory it will be done by the mem_root but
+      we need to call the destructor because we free other resources
+      which are not allocated on the root but on the heap, or we
+      deinit mutexes.
+    */
+    DBUG_ASSERT(0);
+  }
+
+
   Event_timed():in_spawned_thread(0),locked_by_thread_id(0),
                 running(0), status_changed(false),
                 last_executed_changed(false), expression(0), created(0),
@@ -136,15 +168,21 @@ class Event_timed
   }
 
   ~Event_timed()
-  {
-    pthread_mutex_destroy(&this->LOCK_running);
+  {    
+    deinit_mutexes();
+
     if (free_sphead_on_delete)
-	    free_sp();
+      free_sp();
   }
 
-
   void
   init();
+  
+  void
+  deinit_mutexes()
+  {
+    pthread_mutex_destroy(&this->LOCK_running);
+  }
 
   int
   init_definer(THD *thd);
diff --git a/sql/event_timed.cc b/sql/event_timed.cc
index 8348a75914e90c4c3c722bf1edb7a518cd531053..b0e818a4e483d27faaaa4ae27c2d49a82ef5c8a7 100644
--- a/sql/event_timed.cc
+++ b/sql/event_timed.cc
@@ -1228,12 +1228,12 @@ Event_timed::change_security_context(THD *thd, Security_context *s_ctx,
                              definer_host.str, dbname.str))
   {
     my_error(ER_NO_SUCH_USER, MYF(0), definer_user.str, definer_host.str);
-    DBUG_RETURN(TRUE);
+    DBUG_RETURN(true);
   }
   *backup= thd->security_ctx;
   thd->security_ctx= s_ctx;
 #endif
-  DBUG_RETURN(FALSE);
+  DBUG_RETURN(false);
 }
 
 
@@ -1368,7 +1368,8 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
   ret= 0;
 done:
   lex.et->free_sphead_on_delete= false;
-  delete lex.et;
+  lex.et->deinit_mutexes();
+
   lex_end(&lex);
   DBUG_PRINT("note", ("return old data on its place. set back NAMES"));
 
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 96c6c7fa8f3348e41078383945eba99c79b2c8db..77dfcfe862a6334f2fca96cdb47e4b65e8228318 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3803,10 +3803,14 @@ mysql_execute_command(THD *thd)
         send_ok(thd, rows_affected);
 
       /* lex->unit.cleanup() is called outside, no need to call it here */
-    } while (0);  
-    lex->et->free_sphead_on_delete= true;
-    delete lex->et;
-    lex->et= 0;
+    } while (0);
+    if (!thd->spcont)
+    {
+      lex->et->free_sphead_on_delete= true;
+      lex->et->free_sp();
+      lex->et->deinit_mutexes();
+    }
+    
     break;
   }
   case SQLCOM_SHOW_CREATE_EVENT:
@@ -5845,7 +5849,9 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
           if (thd->lex->et)
           {
             thd->lex->et->free_sphead_on_delete= true;
-            delete thd->lex->et;
+            /* alloced on thd->mem_root so no real memory free but dtor call */
+            thd->lex->et->free_sp();
+            thd->lex->et->deinit_mutexes();
             thd->lex->et= NULL;
           }
 	}
@@ -5886,7 +5892,8 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
       if (thd->lex->et)
       {
         thd->lex->et->free_sphead_on_delete= true;
-        delete thd->lex->et;
+        lex->et->free_sp();
+        lex->et->deinit_mutexes();
         thd->lex->et= NULL;
       }
     }
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 15012571369b2ea0bd16f032d788ef8f694b0602..9accacbd7b4d186d23208a5f9323bb33fade262b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1275,7 +1275,7 @@ create:
 
             lex->create_info.options= $3;
 
-            if (!(lex->et= new Event_timed())) // implicitly calls Event_timed::init()
+            if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls Event_timed::init()
               YYABORT;
 
             /*
@@ -4813,7 +4813,7 @@ alter:
             }
             lex->spname= 0;//defensive programming
 
-            if (!(et= new Event_timed()))// implicitly calls Event_timed::init()
+            if (!(et= new (YYTHD->mem_root) Event_timed()))// implicitly calls Event_timed::init()
               YYABORT;
             lex->et = et;
 
@@ -7717,7 +7717,7 @@ drop:
               YYABORT;
             }
 
-            if (!(lex->et= new Event_timed()))
+            if (!(lex->et= new (YYTHD->mem_root) Event_timed()))
               YYABORT;
 	  
             if (!lex->et_compile_phase)
@@ -8441,7 +8441,7 @@ show_param:
           {
             Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
             Lex->spname= $3;
-            Lex->et= new Event_timed();
+            Lex->et= new (YYTHD->mem_root) Event_timed();
             if (!Lex->et)
               YYABORT;
             Lex->et->init_definer(YYTHD);