diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 9a977e2a521..9281d40bd60 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -67,6 +67,7 @@
 #define MAX_COLUMNS            256
 #define MAX_EMBEDDED_SERVER_ARGS 64
 #define MAX_DELIMITER_LENGTH 16
+#define DEFAULT_MAX_CONN       128
 
 /* Flags controlling send and reap */
 #define QUERY_SEND_FLAG  1
@@ -79,8 +80,8 @@ static int setenv(const char *name, const char *value, int overwrite);
 enum {
   OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
   OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
-  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
-  OPT_RESULT_FORMAT_VERSION
+  OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS, OPT_MARK_PROGRESS,
+  OPT_LOG_DIR, OPT_TAIL_LINES, OPT_RESULT_FORMAT_VERSION, 
 };
 
 static int record= 0, opt_sleep= -1;
@@ -92,6 +93,7 @@ const char *opt_include= 0, *opt_charsets_dir;
 static int opt_port= 0;
 static int opt_max_connect_retries;
 static int opt_result_format_version;
+static int opt_max_connections= DEFAULT_MAX_CONN;
 static my_bool opt_compress= 0, silent= 0, verbose= 0;
 static my_bool debug_info_flag= 0, debug_check_flag= 0;
 static my_bool tty_password= 0;
@@ -101,7 +103,7 @@ static my_bool sp_protocol= 0, sp_protocol_enabled= 0;
 static my_bool view_protocol= 0, view_protocol_enabled= 0;
 static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0;
 static my_bool parsing_disabled= 0;
-static my_bool display_result_vertically= FALSE,
+static my_bool display_result_vertically= FALSE, display_result_lower= FALSE,
   display_metadata= FALSE, display_result_sorted= FALSE;
 static my_bool disable_query_log= 0, disable_result_log= 0;
 static my_bool disable_warnings= 0;
@@ -138,6 +140,7 @@ struct st_block
   int             line; /* Start line of block */
   my_bool         ok;   /* Should block be executed */
   enum block_cmd  cmd;  /* Command owning the block */
+  char            delim[MAX_DELIMITER_LENGTH];  /* Delimiter before block */
 };
 
 static struct st_block block_stack[32];
@@ -233,6 +236,8 @@ struct st_connection
   char *name;
   size_t name_len;
   MYSQL_STMT* stmt;
+  /* Set after send to disallow other queries before reap */
+  my_bool pending;
 
 #ifdef EMBEDDED_LIBRARY
   const char *cur_query;
@@ -242,7 +247,8 @@ struct st_connection
   int query_done;
 #endif /*EMBEDDED_LIBRARY*/
 };
-struct st_connection connections[128];
+
+struct st_connection *connections= NULL;
 struct st_connection* cur_con= NULL, *next_con, *connections_end;
 
 /*
@@ -276,6 +282,7 @@ enum enum_commands {
   Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR,
   Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS,
   Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT,
+  Q_LOWERCASE,
   Q_START_TIMER, Q_END_TIMER,
   Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL,
   Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT,
@@ -288,7 +295,7 @@ enum enum_commands {
   Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
   Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
   Q_RESULT_FORMAT_VERSION,
-  Q_MOVE_FILE, Q_SEND_EVAL,
+  Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL,
   Q_UNKNOWN,			       /* Unknown command.   */
   Q_COMMENT,			       /* Comments, ignored. */
   Q_COMMENT_WITH_COMMAND,
@@ -348,6 +355,7 @@ const char *command_names[]=
   "query_vertical",
   "query_horizontal",
   "sorted_result",
+  "lowercase_result",
   "start_timer",
   "end_timer",
   "character_set",
@@ -384,6 +392,7 @@ const char *command_names[]=
   "shutdown_server",
   "result_format",
   "move_file",
+  "remove_files_wildcard",
   "send_eval",
 
   0
@@ -488,6 +497,8 @@ void free_replace();
 void do_get_replace_regex(struct st_command *command);
 void free_replace_regex();
 
+/* Used by sleep */
+void check_eol_junk_line(const char *eol);
 
 void free_all_replace(){
   free_replace();
@@ -1034,7 +1045,7 @@ void check_command_args(struct st_command *command,
   }
   /* Check for too many arguments passed */
   ptr= command->last_argument;
-  while(ptr <= command->end)
+  while(ptr <= command->end && *ptr != '#')
   {
     if (*ptr && *ptr != ' ')
       die("Extra argument '%s' passed to '%.*s'",
@@ -1092,6 +1103,7 @@ void close_connections()
       mysql_close(next_con->util_mysql);
     my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR));
   }
+  my_free(connections, MYF(MY_WME));
   DBUG_VOID_RETURN;
 }
 
@@ -1118,7 +1130,7 @@ void close_files()
     if (cur_file->file && cur_file->file != stdin)
     {
       DBUG_PRINT("info", ("closing file: %s", cur_file->file_name));
-      my_fclose(cur_file->file, MYF(0));
+      fclose(cur_file->file);
     }
     my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
     cur_file->file_name= 0;
@@ -1132,7 +1144,8 @@ void free_used_memory()
   uint i;
   DBUG_ENTER("free_used_memory");
 
-  close_connections();
+  if (connections)
+    close_connections();
   close_files();
   my_hash_free(&var_hash);
 
@@ -2493,7 +2506,7 @@ int open_file(const char *name)
   if (cur_file == file_stack_end)
     die("Source directives are nesting too deep");
   cur_file++;
-  if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
+  if (!(cur_file->file = fopen(buff, "rb")))
   {
     cur_file--;
     die("Could not open '%s' for reading, errno: %d", buff, errno);
@@ -2705,6 +2718,10 @@ void do_exec(struct st_command *command)
 #endif
 #endif
 
+  /* exec command is interpreted externally and will not take newlines */
+  while(replace(&ds_cmd, "\n", 1, " ", 1) == 0)
+    ;
+  
   DBUG_PRINT("info", ("Executing '%s' as '%s'",
                       command->first_argument, ds_cmd.str));
 
@@ -2928,6 +2945,81 @@ void do_remove_file(struct st_command *command)
 }
 
 
+/*
+  SYNOPSIS
+  do_remove_files_wildcard
+  command	called command
+
+  DESCRIPTION
+  remove_files_wildcard <directory> [<file_name_pattern>]
+  Remove the files in <directory> optionally matching <file_name_pattern>
+*/
+
+void do_remove_files_wildcard(struct st_command *command)
+{
+  int error= 0;
+  uint i;
+  MY_DIR *dir_info;
+  FILEINFO *file;
+  char dir_separator[2];
+  static DYNAMIC_STRING ds_directory;
+  static DYNAMIC_STRING ds_wild;
+  static DYNAMIC_STRING ds_file_to_remove;
+  char dirname[FN_REFLEN];
+  
+  const struct command_arg rm_args[] = {
+    { "directory", ARG_STRING, TRUE, &ds_directory,
+      "Directory containing files to delete" },
+    { "filename", ARG_STRING, FALSE, &ds_wild, "File pattern to delete" }
+  };
+  DBUG_ENTER("do_remove_files_wildcard");
+
+  check_command_args(command, command->first_argument,
+                     rm_args, sizeof(rm_args)/sizeof(struct command_arg),
+                     ' ');
+  fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME);
+
+  DBUG_PRINT("info", ("listing directory: %s", dirname));
+  /* Note that my_dir sorts the list if not given any flags */
+  if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT))))
+  {
+    error= 1;
+    goto end;
+  }
+  init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024);
+  dir_separator[0]= FN_LIBCHAR;
+  dir_separator[1]= 0;
+  dynstr_append(&ds_file_to_remove, dir_separator);
+  for (i= 0; i < (uint) dir_info->number_off_files; i++)
+  {
+    file= dir_info->dir_entry + i;
+    /* Remove only regular files, i.e. no directories etc. */
+    /* if (!MY_S_ISREG(file->mystat->st_mode)) */
+    /* MY_S_ISREG does not work here on Windows, just skip directories */
+    if (MY_S_ISDIR(file->mystat->st_mode))
+      continue;
+    if (ds_wild.length &&
+        wild_compare(file->name, ds_wild.str, 0))
+      continue;
+    ds_file_to_remove.length= ds_directory.length + 1;
+    ds_file_to_remove.str[ds_directory.length + 1]= 0;
+    dynstr_append(&ds_file_to_remove, file->name);
+    DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str));
+    error= my_delete(ds_file_to_remove.str, MYF(0)) != 0;
+    if (error)
+      break;
+  }
+  my_dirend(dir_info);
+
+end:
+  handle_command_error(command, error);
+  dynstr_free(&ds_directory);
+  dynstr_free(&ds_wild);
+  dynstr_free(&ds_file_to_remove);
+  DBUG_VOID_RETURN;
+}
+
+
 /*
   SYNOPSIS
   do_copy_file
@@ -3688,49 +3780,58 @@ void do_perl(struct st_command *command)
                      sizeof(perl_args)/sizeof(struct command_arg),
                      ' ');
 
-  /* If no delimiter was provided, use EOF */
-  if (ds_delimiter.length == 0)
-    dynstr_set(&ds_delimiter, "EOF");
-
-  init_dynamic_string(&ds_script, "", 1024, 1024);
-  read_until_delimiter(&ds_script, &ds_delimiter);
-
-  DBUG_PRINT("info", ("Executing perl: %s", ds_script.str));
-
-  /* Create temporary file name */
-  if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
-                            "tmp", O_CREAT | O_SHARE | O_RDWR,
-                            MYF(MY_WME))) < 0)
-    die("Failed to create temporary file for perl command");
-  my_close(fd, MYF(0));
-
-  str_to_file(temp_file_path, ds_script.str, ds_script.length);
-
-  /* Format the "perl <filename>" command */
-  my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
-
-  if (!(res_file= popen(buf, "r")) && command->abort_on_error)
-    die("popen(\"%s\", \"r\") failed", buf);
-
-  while (fgets(buf, sizeof(buf), res_file))
+  ds_script= command->content;
+  /* If it hasn't been done already by a loop iteration, fill it in */
+  if (! ds_script.str)
   {
-    if (disable_result_log)
-    {
-      buf[strlen(buf)-1]=0;
-      DBUG_PRINT("exec_result",("%s", buf));
-    }
-    else
-    {
-      replace_dynstr_append(&ds_res, buf);
-    }
+    /* If no delimiter was provided, use EOF */
+    if (ds_delimiter.length == 0)
+      dynstr_set(&ds_delimiter, "EOF");
+
+    init_dynamic_string(&ds_script, "", 1024, 1024);
+    read_until_delimiter(&ds_script, &ds_delimiter);
+    command->content= ds_script;
   }
-  error= pclose(res_file);
 
-  /* Remove the temporary file */
-  my_delete(temp_file_path, MYF(0));
+  /* This function could be called even if "false", so check before doing */
+  if (cur_block->ok)
+  {
+    DBUG_PRINT("info", ("Executing perl: %s", ds_script.str));
 
-  handle_command_error(command, WEXITSTATUS(error));
-  dynstr_free(&ds_script);
+    /* Create temporary file name */
+    if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
+                              "tmp", O_CREAT | O_SHARE | O_RDWR,
+                              MYF(MY_WME))) < 0)
+      die("Failed to create temporary file for perl command");
+    my_close(fd, MYF(0));
+
+    str_to_file(temp_file_path, ds_script.str, ds_script.length);
+
+    /* Format the "perl <filename>" command */
+    my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
+
+    if (!(res_file= popen(buf, "r")) && command->abort_on_error)
+     die("popen(\"%s\", \"r\") failed", buf);
+
+    while (fgets(buf, sizeof(buf), res_file))
+    {
+      if (disable_result_log)
+      {
+	buf[strlen(buf)-1]=0;
+	DBUG_PRINT("exec_result",("%s", buf));
+      }
+      else
+      {
+	replace_dynstr_append(&ds_res, buf);
+      }
+    }
+    error= pclose(res_file);
+
+    /* Remove the temporary file */
+    my_delete(temp_file_path, MYF(0));
+
+    handle_command_error(command, WEXITSTATUS(error));
+  }
   dynstr_free(&ds_delimiter);
   DBUG_VOID_RETURN;
 }
@@ -4138,10 +4239,19 @@ void do_let(struct st_command *command)
 int do_sleep(struct st_command *command, my_bool real_sleep)
 {
   int error= 0;
-  char *p= command->first_argument;
-  char *sleep_start, *sleep_end= command->end;
+  char *sleep_start, *sleep_end;
   double sleep_val;
+  char *p;
+  static DYNAMIC_STRING ds_sleep;
+  const struct command_arg sleep_args[] = {
+    { "sleep_delay", ARG_STRING, TRUE, &ds_sleep, "Number of seconds to sleep." }
+  };
+  check_command_args(command, command->first_argument, sleep_args,
+                     sizeof(sleep_args)/sizeof(struct command_arg),
+                     ' ');
 
+  p= ds_sleep.str;
+  sleep_end= ds_sleep.str + ds_sleep.length;
   while (my_isspace(charset_info, *p))
     p++;
   if (!*p)
@@ -4150,11 +4260,13 @@ int do_sleep(struct st_command *command, my_bool real_sleep)
   /* Check that arg starts with a digit, not handled by my_strtod */
   if (!my_isdigit(charset_info, *sleep_start))
     die("Invalid argument to %.*s \"%s\"", command->first_word_len,
-        command->query,command->first_argument);
+        command->query, sleep_start);
   sleep_val= my_strtod(sleep_start, &sleep_end, &error);
+  check_eol_junk_line(sleep_end);
   if (error)
     die("Invalid argument to %.*s \"%s\"", command->first_word_len,
         command->query, command->first_argument);
+  dynstr_free(&ds_sleep);
 
   /* Fixed sleep time selected by --sleep option */
   if (opt_sleep >= 0 && !real_sleep)
@@ -4163,7 +4275,6 @@ int do_sleep(struct st_command *command, my_bool real_sleep)
   DBUG_PRINT("info", ("sleep_val: %f", sleep_val));
   if (sleep_val)
     my_sleep((ulong) (sleep_val * 1000000L));
-  command->last_argument= sleep_end;
   return 0;
 }
 
@@ -4701,7 +4812,8 @@ void do_close_connection(struct st_command *command)
   if (con->util_mysql)
     mysql_close(con->util_mysql);
   con->util_mysql= 0;
-
+  con->pending= FALSE;
+  
   my_free(con->name, MYF(0));
 
   /*
@@ -5035,7 +5147,7 @@ void do_connect(struct st_command *command)
   {
     if (!(con_slot= find_connection_by_name("-closed_connection-")))
       die("Connection limit exhausted, you can have max %d connections",
-          (int) (sizeof(connections)/sizeof(struct st_connection)));
+          opt_max_connections);
   }
 
 #ifdef EMBEDDED_LIBRARY
@@ -5154,6 +5266,12 @@ int do_done(struct st_command *command)
   }
   else
   {
+    if (*cur_block->delim) 
+    {
+      /* Restore "old" delimiter after false if block */
+      strcpy (delimiter, cur_block->delim);
+      delimiter_length= strlen(delimiter);
+    }
     /* Pop block from stack, goto next line */
     cur_block--;
     parser.current_line++;
@@ -5212,6 +5330,7 @@ void do_block(enum block_cmd cmd, struct st_command* command)
     cur_block++;
     cur_block->cmd= cmd;
     cur_block->ok= FALSE;
+    cur_block->delim[0]= '\0';
     DBUG_VOID_RETURN;
   }
 
@@ -5248,6 +5367,15 @@ void do_block(enum block_cmd cmd, struct st_command* command)
   if (not_expr)
     cur_block->ok = !cur_block->ok;
 
+  if (cur_block->ok) 
+  {
+    cur_block->delim[0]= '\0';
+  } else
+  {
+    /* Remember "old" delimiter if entering a false if block */
+    strcpy (cur_block->delim, delimiter);
+  }
+  
   DBUG_PRINT("info", ("OK: %d", cur_block->ok));
 
   var_free(&v);
@@ -5350,7 +5478,7 @@ int read_line(char *buf, int size)
   found_eof:
       if (cur_file->file != stdin)
       {
-	my_fclose(cur_file->file, MYF(0));
+	fclose(cur_file->file);
         cur_file->file= 0;
       }
       my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
@@ -5790,6 +5918,10 @@ static struct my_option my_long_options[] =
    "Max number of connection attempts when connecting to server",
    (uchar**) &opt_max_connect_retries, (uchar**) &opt_max_connect_retries, 0,
    GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
+  {"max-connections", OPT_MAX_CONNECTIONS,
+   "Max number of open connections to server",
+   (uchar**) &opt_max_connections, (uchar**) &opt_max_connections, 0,
+   GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0},
   {"password", 'p', "Password to use when connecting to server.",
    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
   {"port", 'P', "Port number to use for connection or 0 for default to, in "
@@ -5960,7 +6092,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
     fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
     DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0);
     if (!(cur_file->file=
-          my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
+          fopen(buff, "rb")))
       die("Could not open '%s' for reading, errno: %d", buff, errno);
     cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
     cur_file->lineno= 1;
@@ -6579,8 +6711,11 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
     wait_query_thread_end(cn);
 #endif /*EMBEDDED_LIBRARY*/
   if (!(flags & QUERY_REAP_FLAG))
+  {
+    cn->pending= TRUE;
     DBUG_VOID_RETURN;
-
+  }
+  
   do
   {
     /*
@@ -6664,6 +6799,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
 
 end:
 
+  cn->pending= FALSE;
   /*
     We save the return code (mysql_errno(mysql)) from the last call sent
     to the server into the mysqltest builtin variable $mysql_errno. This
@@ -7140,6 +7276,9 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
 
   init_dynamic_string(&ds_warnings, NULL, 0, 256);
 
+  if (cn->pending && (flags & QUERY_SEND_FLAG))
+    die ("Cannot run query on connection between send and reap");
+
   /*
     Evaluate query if this is an eval command
   */
@@ -7662,12 +7801,6 @@ int main(int argc, char **argv)
   /* Init expected errors */
   memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
 
-  /* Init connections */
-  memset(connections, 0, sizeof(connections));
-  connections_end= connections +
-    (sizeof(connections)/sizeof(struct st_connection)) - 1;
-  next_con= connections + 1;
-
 #ifdef EMBEDDED_LIBRARY
   /* set appropriate stack for the 'query' threads */
   (void) pthread_attr_init(&cn_thd_attrib);
@@ -7694,7 +7827,14 @@ int main(int argc, char **argv)
                    1024, 0, 0, get_var_key, var_free, MYF(0)))
     die("Variable hash initialization failed");
 
-  var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
+  var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION);
+  var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE);
+  var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE);
+  if (sizeof(void *) == 8) {
+    var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "64");
+  } else {
+    var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "32");
+  }
 
   memset(&master_pos, 0, sizeof(master_pos));
 
@@ -7722,6 +7862,13 @@ int main(int argc, char **argv)
     verbose_msg("Tracing progress in '%s'.", progress_file.file_name());
   }
 
+  /* Init connections, allocate 1 extra as buffer + 1 for default */
+  connections= (struct st_connection*)
+    my_malloc((opt_max_connections+2) * sizeof(struct st_connection),
+              MYF(MY_WME | MY_ZEROFILL));
+  connections_end= connections + opt_max_connections +1;
+  next_con= connections + 1;
+  
   var_set_int("$PS_PROTOCOL", ps_protocol);
   var_set_int("$SP_PROTOCOL", sp_protocol);
   var_set_int("$VIEW_PROTOCOL", view_protocol);
@@ -7825,7 +7972,8 @@ int main(int argc, char **argv)
       command->type= Q_COMMENT;
     }
 
-    my_bool ok_to_do= cur_block->ok;
+    /* delimiter needs to be executed so we can continue to parse */
+    my_bool ok_to_do= cur_block->ok || command->type == Q_DELIMITER;
     /*
       Some commands need to be "done" the first time if they may get
       re-iterated over in a true context. This can only happen if there's 
@@ -7883,6 +8031,7 @@ int main(int argc, char **argv)
       case Q_ECHO: do_echo(command); command_executed++; break;
       case Q_SYSTEM: do_system(command); break;
       case Q_REMOVE_FILE: do_remove_file(command); break;
+      case Q_REMOVE_FILES_WILDCARD: do_remove_files_wildcard(command); break;
       case Q_MKDIR: do_mkdir(command); break;
       case Q_RMDIR: do_rmdir(command); break;
       case Q_LIST_FILES: do_list_files(command); break;
@@ -7920,6 +8069,13 @@ int main(int argc, char **argv)
         */
 	display_result_sorted= TRUE;
         break;
+      case Q_LOWERCASE:
+        /*
+          Turn on lowercasing of result, will be reset after next
+          command
+        */
+        display_result_lower= TRUE;
+        break;
       case Q_LET: do_let(command); break;
       case Q_EVAL_RESULT:
         die("'eval_result' command  is deprecated");
@@ -8164,8 +8320,9 @@ int main(int argc, char **argv)
       */
       free_all_replace();
 
-      /* Also reset "sorted_result" */
+      /* Also reset "sorted_result" and "lowercase"*/
       display_result_sorted= FALSE;
+      display_result_lower= FALSE;
     }
     last_command_executed= command_executed;
 
@@ -9505,7 +9662,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name)
   if (pa->length+length >= pa->max_length)
   {
     if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str,
-				      (uint) (pa->max_length+PS_MALLOC),
+                                      (uint) (pa->length+length+PS_MALLOC),
 				      MYF(MY_WME))))
       DBUG_RETURN(1);
     if (new_pos != pa->str)
@@ -9516,7 +9673,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name)
 					      char*);
       pa->str=new_pos;
     }
-    pa->max_length+=PS_MALLOC;
+    pa->max_length= pa->length+length+PS_MALLOC;
   }
   if (pa->typelib.count >= pa->max_count-1)
   {
@@ -9569,6 +9726,18 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
   fix_win_paths(val, len);
 #endif
 
+  if (display_result_lower) 
+  {
+    /* Convert to lower case, and do this first */
+    char lower[512];
+    char *c= lower;
+    for (const char *v= val;  *v;  v++)
+      *c++= my_tolower(charset_info, *v);
+    *c= '\0';
+    /* Copy from this buffer instead */
+    val= lower;
+  }
+  
   if (glob_replace_regex)
   {
     /* Regex replace */
diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc
index 4b2e64e3bb5..2de514f27bb 100644
--- a/mysql-test/include/handler.inc
+++ b/mysql-test/include/handler.inc
@@ -774,6 +774,7 @@ connection default;
 handler t1 read a next;
 handler t1 close;
 connection con1;
+--reap # Since last in this connection was a send
 drop table t1;
 disconnect con1;
 --source include/wait_until_disconnected.inc
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index e62dba8ae82..9378329353b 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -194,6 +194,27 @@ INSERT INTO global_suppressions VALUES
  ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),
  ("Slave I/O: Get master TIME_ZONE failed with error:.*"),
 
+ /* Messages from valgrind */
+ ("==[0-9]*== Memcheck,"),
+ ("==[0-9]*== Copyright"),
+ ("==[0-9]*== Using"),
+ ("==[0-9]*== For more details"),
+ /* This comes with innodb plugin tests */
+ ("==[0-9]*== Warning: set address range perms: large range"),
+
+ /* valgrind warnings: invalid file descriptor -1 in syscall
+    write()/read(). Bug #50414 */
+ ("==[0-9]*== Warning: invalid file descriptor -1 in syscall write()"),
+ ("==[0-9]*== Warning: invalid file descriptor -1 in syscall read()"),
+
+ /*
+   Transient network failures that cause warnings on reconnect.
+   BUG#47743 and BUG#47983.
+ */
+ ("Slave I/O: Get master SERVER_ID failed with error:.*"),
+ ("Slave I/O: Get master clock failed with error:.*"),
+ ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),
+ ("Slave I/O: Get master TIME_ZONE failed with error:.*"),
  /*
    BUG#42147 - Concurrent DML and LOCK TABLE ... READ for InnoDB 
    table cause warnings in errlog
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm
index 0fac25b814b..b8f05778b6e 100644
--- a/mysql-test/lib/My/SafeProcess.pm
+++ b/mysql-test/lib/My/SafeProcess.pm
@@ -81,7 +81,6 @@ sub is_child {
 }
 
 
-# Find the safe process binary or script
 my @safe_process_cmd;
 my $safe_kill;
 my $bindir;
@@ -96,21 +95,26 @@ else
   $bindir = ".";
 }
 
-if (IS_WIN32PERL or IS_CYGWIN){
-  # Use my_safe_process.exe
-  my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"],
-		       "my_safe_process");
-  push(@safe_process_cmd, $exe);
 
-  # Use my_safe_kill.exe
-  $safe_kill= my_find_bin($bindir, "lib/My/SafeProcess", "my_safe_kill");
-}
-else
-{
-  # Use my_safe_process
-  my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"],
-		       "my_safe_process");
-  push(@safe_process_cmd, $exe);
+# Find the safe process binary or script
+sub find_bin {
+  if (IS_WIN32PERL or IS_CYGWIN)
+  {
+    # Use my_safe_process.exe
+    my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"],
+			 "my_safe_process");
+    push(@safe_process_cmd, $exe);
+
+    # Use my_safe_kill.exe
+    $safe_kill= my_find_bin($bindir, "lib/My/SafeProcess", "my_safe_kill");
+  }
+  else
+  {
+    # Use my_safe_process
+    my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"],
+			 "my_safe_process");
+    push(@safe_process_cmd, $exe);
+  }
 }
 
 
@@ -195,63 +199,6 @@ sub run {
   return $proc->exit_status();
 }
 
-#
-# Start a process that returns after "duration" seconds
-# or when it's parent process does not exist anymore
-#
-sub timer {
-  my $class= shift;
-  my $duration= shift or croak "duration required";
-  my $parent_pid= $$;
-
-  my $pid= My::SafeProcess::Base::_safe_fork();
-  if ($pid){
-    # Parent
-    my $proc= bless
-      ({
-	SAFE_PID  => $pid,
-	SAFE_NAME => "timer",
-	PARENT => $$,
-       }, $class);
-
-    # Put the new process in list of running
-    $running{$pid}= $proc;
-    return $proc;
-  }
-
-  # Child, install signal handlers and sleep for "duration"
-  $SIG{INT}= 'IGNORE';
-
-  $SIG{TERM}= sub {
-    #print STDERR "timer $$: woken up, exiting!\n";
-    exit(0);
-  };
-
-  $0= "safe_timer($duration)";
-
-  if (IS_WIN32PERL){
-    # Just a thread in same process
-    sleep($duration);
-    print STDERR "timer $$: expired after $duration seconds\n";
-    exit(0);
-  }
-
-  my $count_down= $duration;
-  while($count_down--){
-
-    # Check that parent is still alive
-    if (kill(0, $parent_pid) == 0){
-      #print STDERR "timer $$: parent gone, exiting!\n";
-      exit(0);
-    }
-
-    sleep(1);
-  }
-  print STDERR "timer $$: expired after $duration seconds\n";
-  exit(0);
-}
-
-
 #
 # Shutdown process nicely, and wait for shutdown_timeout seconds
 # If processes hasn't shutdown, kill them hard and wait for return
@@ -350,12 +297,12 @@ sub start_kill {
     $ret= system($safe_kill, $winpid) >> 8;
 
     if ($ret == 3){
-      print "Couldn't open the winpid: $winpid ",
+      print "Couldn't open the winpid: $winpid ".
 	"for pid: $pid, try one more time\n";
       sleep(1);
       $winpid= _winpid($pid);
       $ret= system($safe_kill, $winpid) >> 8;
-      print "Couldn't open the winpid: $winpid ",
+      print "Couldn't open the winpid: $winpid ".
 	"for pid: $pid, continue and see what happens...\n";
     }
   }
@@ -549,6 +496,40 @@ sub wait_any {
 }
 
 
+#
+# Wait for any process to exit, or a timeout
+#
+# Returns a reference to the SafeProcess that
+# exited or a pseudo-process with $proc->{timeout} == 1
+#
+
+sub wait_any_timeout {
+  my $class= shift;
+  my $timeout= shift;
+  my $proc;
+  my $millis=10;
+
+  do {
+    ::mtr_milli_sleep($millis);
+    # Slowly increse interval up to max. 1 second
+    $millis++ if $millis < 1000;
+    # Return a "fake" process for timeout
+    if (::has_expired($timeout)) {
+      $proc= bless
+	({
+	  SAFE_PID  => 0,
+	  SAFE_NAME => "timer",
+	  timeout => 1,
+	 }, $class);
+    } else {
+      $proc= check_any();
+    }
+  } while (! $proc);
+
+  return $proc;
+}
+
+
 #
 # Wait for all processes to exit
 #
@@ -606,7 +587,7 @@ sub self2str {
 
 sub _verbose {
   return unless $_verbose;
-  print STDERR " ## ", @_, "\n";
+  print STDERR " ## ". @_. "\n";
 }
 
 
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 7b47fcbe2dd..8fffede0b62 100755
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -187,14 +187,20 @@ int main(int argc, const char** argv )
         die("No real args -> nothing to do");
       /* Copy the remaining args to child_arg */
       for (int j= i+1; j < argc; j++) {
-	if (strchr (argv[j], ' ')) {
-	  /* Protect with "" if this arg contains a space */
-	  to+= _snprintf(to, child_args + sizeof(child_args) - to,
-                         "\"%s\" ", argv[j]);
-	} else {
-	  to+= _snprintf(to, child_args + sizeof(child_args) - to,
-	                 "%s ", argv[j]);
-	}
+        arg= argv[j];
+        if (strchr (arg, ' ') &&
+            arg[0] != '\"' &&
+            arg[strlen(arg)] != '\"')
+        {
+          /* Quote arg that contains spaces and are not quoted already */
+          to+= _snprintf(to, child_args + sizeof(child_args) - to,
+                         "\"%s\" ", arg);
+        }
+        else
+        {
+          to+= _snprintf(to, child_args + sizeof(child_args) - to,
+          "%s ", arg);
+        }
       }
       break;
     } else {
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 8d02914c1e3..7b7dd70a696 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -40,7 +40,6 @@ our $default_storage_engine;
 our $opt_with_ndbcluster_only;
 our $defaults_file;
 our $defaults_extra_file;
-our $reorder= 1;
 our $quick_collect;
 
 sub collect_option {
@@ -99,7 +98,8 @@ sub init_pattern {
 #
 ##############################################################################
 
-sub collect_test_cases ($$) {
+sub collect_test_cases ($$$) {
+  my $opt_reorder= shift; # True if we're reordering tests
   my $suites= shift; # Semicolon separated list of test suites
   my $opt_cases= shift;
   my $cases= []; # Array of hash(one hash for each testcase)
@@ -118,10 +118,16 @@ sub collect_test_cases ($$) {
 		      !(IS_WINDOWS && $::opt_embedded_server) &&
 		      $lib_innodb_plugin);
 
-  foreach my $suite (split(",", $suites))
+  # If not reordering, we also shouldn't group by suites, unless
+  # no test cases were named.
+  # This also effects some logic in the loop following this.
+  if ($opt_reorder or !@$opt_cases)
   {
-    push(@$cases, collect_one_suite($suite, $opt_cases));
-    last if $some_test_found;
+    foreach my $suite (split(",", $suites))
+    {
+      push(@$cases, collect_one_suite($suite, $opt_cases));
+      last if $some_test_found;
+    }
   }
 
   if ( @$opt_cases )
@@ -135,6 +141,7 @@ sub collect_test_cases ($$) {
       my ($sname, $tname, $extension)= split_testname($test_name_spec);
       foreach my $test ( @$cases )
       {
+	last unless $opt_reorder;
 	# test->{name} is always in suite.name format
 	if ( $test->{name} =~ /.*\.$tname/ )
 	{
@@ -144,12 +151,13 @@ sub collect_test_cases ($$) {
       }
       if ( not $found )
       {
+	$sname= "main" if !$opt_reorder and !$sname;
 	mtr_error("Could not find '$tname' in '$suites' suite(s)") unless $sname;
-	# If suite was part of name, find it there
-	my ($this_case) = collect_one_suite($sname, [ $tname ]);
-	if ($this_case)
+	# If suite was part of name, find it there, may come with combinations
+	my @this_case = collect_one_suite($sname, [ $tname ]);
+	if (@this_case)
         {
-	  push (@$cases, $this_case);
+	  push (@$cases, @this_case);
 	}
 	else
 	{
@@ -159,7 +167,7 @@ sub collect_test_cases ($$) {
     }
   }
 
-  if ( $reorder && !$quick_collect)
+  if ( $opt_reorder && !$quick_collect)
   {
     # Reorder the test cases in an order that will make them faster to run
     my %sort_criteria;
diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl
index f6615301dd7..5820a4007b8 100644
--- a/mysql-test/lib/mtr_gprof.pl
+++ b/mysql-test/lib/mtr_gprof.pl
@@ -20,43 +20,20 @@
 
 use strict;
 
-# These are not to be prefixed with "mtr_"
+sub gprof_collect ($@) {
+  my ($exe_mysqld, @gprof_dirs)= @_;
 
-sub gprof_prepare ();
-sub gprof_collect ();
+  print ("Collecting gprof reports.....\n");
 
-##############################################################################
-#
-#  
-#
-##############################################################################
-
-sub gprof_prepare () {
-
-  rmtree($::opt_gprof_dir);
-  mkdir($::opt_gprof_dir);
-}
-
-# FIXME what about master1 and slave1?!
-sub gprof_collect () {
-
-  if ( -f "$::master->[0]->{'path_myddir'}/gmon.out" )
+  foreach my $datadir (@gprof_dirs)
   {
-    # FIXME check result code?!
-    mtr_run("gprof",
-            [$::exe_master_mysqld,
-             "$::master->[0]->{'path_myddir'}/gmon.out"],
-            $::opt_gprof_master, "", "", "");
-    print "Master execution profile has been saved in $::opt_gprof_master\n";
-  }
-  if ( -f "$::slave->[0]->{'path_myddir'}/gmon.out" )
-  {
-    # FIXME check result code?!
-    mtr_run("gprof",
-            [$::exe_slave_mysqld,
-             "$::slave->[0]->{'path_myddir'}/gmon.out"],
-            $::opt_gprof_slave, "", "", "");
-    print "Slave execution profile has been saved in $::opt_gprof_slave\n";
+    my $gprof_msg= "$datadir/gprof.msg";
+    my $gprof_err= "$datadir/gprof.err";
+    if ( -f "$datadir/gmon.out" )
+    {
+      system("gprof $exe_mysqld $datadir/gmon.out 2>$gprof_err >$gprof_msg");
+      print ("GPROF output in $gprof_msg, errors in $gprof_err\n");
+    }
   }
 }
 
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index 658eb270535..97eb693b52e 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -30,7 +30,9 @@ sub mtr_script_exists(@);
 sub mtr_file_exists(@);
 sub mtr_exe_exists(@);
 sub mtr_exe_maybe_exists(@);
-
+sub mtr_milli_sleep($);
+sub start_timer($);
+sub has_expired($);
 
 ##############################################################################
 #
@@ -167,11 +169,18 @@ sub mtr_exe_exists (@) {
 }
 
 
-sub mtr_milli_sleep {
+sub mtr_milli_sleep ($) {
   die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1;
   my ($millis)= @_;
 
   select(undef, undef, undef, ($millis/1000));
 }
 
+# Simple functions to start and check timers (have to be actively polled)
+# Timer can be "killed" by setting it to 0
+
+sub start_timer ($) { return time + $_[0]; }
+
+sub has_expired ($) { return $_[0] && time gt $_[0]; }
+
 1;
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index 937e19111fb..1c4b940bbee 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -69,7 +69,7 @@ sub _mtr_report_test_name ($) {
   $tname.= " '$tinfo->{combination}'"
     if defined $tinfo->{combination};
 
-  print _name(), _timestamp();
+  print _name(). _timestamp();
   printf "%-40s ", $tname;
   my $worker = $tinfo->{worker};
   printf "w$worker " if $worker;
@@ -222,8 +222,8 @@ sub mtr_report_test ($) {
 }
 
 
-sub mtr_report_stats ($;$) {
-  my ($tests, $dont_error)= @_;
+sub mtr_report_stats ($$;$) {
+  my ($prefix, $tests, $dont_error)= @_;
 
   # ----------------------------------------------------------------------
   # Find out how we where doing
@@ -328,6 +328,9 @@ sub mtr_report_stats ($;$) {
     }
   }
 
+  # Print summary line prefix
+  print "$prefix: ";
+
   # Print a list of testcases that failed
   if ( $tot_failed != 0 )
   {
@@ -387,13 +390,13 @@ sub mtr_report_stats ($;$) {
 ##############################################################################
 
 sub mtr_print_line () {
-  print '-' x 60, "\n";
+  print '-' x 60 . "\n";
 }
 
 
 sub mtr_print_thick_line {
   my $char= shift || '=';
-  print $char x 78, "\n";
+  print $char x 78 . "\n";
 }
 
 
@@ -451,7 +454,7 @@ sub _timestamp {
 
 # Always print message to screen
 sub mtr_print (@) {
-  print _name(), join(" ", @_), "\n";
+  print _name(). join(" ", @_). "\n";
 }
 
 
@@ -459,22 +462,22 @@ sub mtr_print (@) {
 sub mtr_report (@) {
   if (defined $verbose)
   {
-    print _name(), join(" ", @_), "\n";
+    print _name(). join(" ", @_). "\n";
   }
 }
 
 
 # Print warning to screen
 sub mtr_warning (@) {
-  print STDERR _name(), _timestamp(),
-    "mysql-test-run: WARNING: ", join(" ", @_), "\n";
+  print STDERR _name(). _timestamp().
+    "mysql-test-run: WARNING: ". join(" ", @_). "\n";
 }
 
 
 # Print error to screen and then exit
 sub mtr_error (@) {
-  print STDERR _name(), _timestamp(),
-    "mysql-test-run: *** ERROR: ", join(" ", @_), "\n";
+  print STDERR _name(). _timestamp().
+    "mysql-test-run: *** ERROR: ". join(" ", @_). "\n";
   if (IS_WINDOWS)
   {
     POSIX::_exit(1);
@@ -489,8 +492,8 @@ sub mtr_error (@) {
 sub mtr_debug (@) {
   if ( $verbose > 2 )
   {
-    print STDERR _name(),
-      _timestamp(), "####: ", join(" ", @_), "\n";
+    print STDERR _name().
+      _timestamp(). "####: ". join(" ", @_). "\n";
   }
 }
 
@@ -498,8 +501,8 @@ sub mtr_debug (@) {
 sub mtr_verbose (@) {
   if ( $verbose )
   {
-    print STDERR _name(), _timestamp(),
-      "> ",join(" ", @_),"\n";
+    print STDERR _name(). _timestamp().
+      "> ".join(" ", @_)."\n";
   }
 }
 
@@ -509,8 +512,8 @@ sub mtr_verbose_restart (@) {
   my $proc= $server->{proc};
   if ( $verbose_restart )
   {
-    print STDERR _name(),_timestamp(),
-      "> Restart $proc - ",join(" ", @args),"\n";
+    print STDERR _name()._timestamp().
+      "> Restart $proc - ".join(" ", @args)."\n";
   }
 }
 
diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl
index cd5c7b0dbb7..702bc178ae5 100644
--- a/mysql-test/lib/mtr_stress.pl
+++ b/mysql-test/lib/mtr_stress.pl
@@ -150,7 +150,7 @@ sub run_stress_test ()
   mtr_add_arg($args, "--verbose");
   mtr_add_arg($args, "--cleanup");
   mtr_add_arg($args, "--log-error-details");
-  mtr_add_arg($args, "--abort-on-error");
+  mtr_add_arg($args, "--abort-on-error=1");
 
   if ( $::opt_stress_init_file )
   {
diff --git a/mysql-test/lib/v1/mtr_stress.pl b/mysql-test/lib/v1/mtr_stress.pl
index 93b06b32c5f..40800c9729b 100644
--- a/mysql-test/lib/v1/mtr_stress.pl
+++ b/mysql-test/lib/v1/mtr_stress.pl
@@ -150,7 +150,7 @@ sub run_stress_test ()
   mtr_add_arg($args, "--verbose");
   mtr_add_arg($args, "--cleanup");
   mtr_add_arg($args, "--log-error-details");
-  mtr_add_arg($args, "--abort-on-error");
+  mtr_add_arg($args, "--abort-on-error=1");
 
   if ( $::opt_stress_init_file )
   {
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index b1e746dd80e..3ea815cb45a 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -905,6 +905,11 @@ sub command_line_setup () {
   mtr_report("Using default engine '$used_default_engine'")
     if defined $used_default_engine;
 
+  if ($glob_win32 and defined $opt_mem) {
+    mtr_report("--mem not supported on Windows, ignored");
+    $opt_mem= undef;
+  }
+
   # --------------------------------------------------------------------------
   # Check if we should speed up tests by trying to run on tmpfs
   # --------------------------------------------------------------------------
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 09703086e66..2fbbdf0b819 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -102,6 +102,7 @@ use IO::Select;
 require "lib/mtr_process.pl";
 require "lib/mtr_io.pl";
 require "lib/mtr_gcov.pl";
+require "lib/mtr_gprof.pl";
 require "lib/mtr_misc.pl";
 
 $SIG{INT}= sub { mtr_error("Got ^C signal"); };
@@ -187,6 +188,9 @@ our $opt_gcov_exe= "gcov";
 our $opt_gcov_err= "mysql-test-gcov.msg";
 our $opt_gcov_msg= "mysql-test-gcov.err";
 
+our $opt_gprof;
+our %gprof_dirs;
+
 our $glob_debugger= 0;
 our $opt_gdb;
 our $opt_client_gdb;
@@ -205,7 +209,9 @@ our $opt_experimental;
 our $experimental_test_cases;
 
 my $baseport;
+# $opt_build_thread may later be set from $opt_port_base
 my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto";
+my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto";
 my $build_thread= 0;
 
 my $opt_record;
@@ -215,6 +221,7 @@ my $opt_skip_core;
 
 our $opt_check_testcases= 1;
 my $opt_mark_progress;
+my $opt_max_connections;
 
 my $opt_sleep;
 
@@ -234,6 +241,7 @@ my $opt_wait_all;
 my $opt_repeat= 1;
 my $opt_retry= 3;
 my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2);
+my $opt_reorder= 1;
 
 my $opt_strace_client;
 
@@ -246,6 +254,7 @@ my @default_valgrind_args= ("--show-reachable=yes");
 my @valgrind_args;
 my $opt_valgrind_path;
 my $opt_callgrind;
+my %mysqld_logs;
 my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
 
 our $opt_warnings= 1;
@@ -285,6 +294,9 @@ sub main {
 
   command_line_setup();
 
+  # --help will not reach here, so now it's safe to assume we have binaries
+  My::SafeProcess::find_bin();
+
   if ( $opt_gcov ) {
     gcov_prepare($basedir);
   }
@@ -314,7 +326,7 @@ sub main {
   }
 
   mtr_report("Collecting tests...");
-  my $tests= collect_test_cases($opt_suites, \@opt_cases);
+  my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases);
 
   if ( $opt_report_features ) {
     # Put "report features" as the first test to run
@@ -431,7 +443,7 @@ sub main {
 		 $opt_gcov_msg, $opt_gcov_err);
   }
 
-  mtr_report_stats($completed);
+  mtr_report_stats("Completed", $completed);
 
   exit(0);
 }
@@ -455,7 +467,7 @@ sub run_test_server ($$$) {
   my $result;
   my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump
 
-  my $suite_timeout_proc= My::SafeProcess->timer(suite_timeout());
+  my $suite_timeout= start_timer(suite_timeout());
 
   my $s= IO::Select->new();
   $s->add($server);
@@ -476,7 +488,6 @@ sub run_test_server ($$$) {
 	  mtr_verbose("Child closed socket");
 	  $s->remove($sock);
 	  if (--$childs == 0){
-	    $suite_timeout_proc->kill();
 	    return $completed;
 	  }
 	  next;
@@ -545,15 +556,13 @@ sub run_test_server ($$$) {
 
 	    if ( !$opt_force ) {
 	      # Test has failed, force is off
-	      $suite_timeout_proc->kill();
 	      push(@$completed, $result);
 	      return $completed;
 	    }
 	    elsif ($opt_max_test_fail > 0 and
 		   $num_failed_test >= $opt_max_test_fail) {
-	      $suite_timeout_proc->kill();
 	      push(@$completed, $result);
-	      mtr_report_stats($completed, 1);
+	      mtr_report_stats("Too many failed", $completed, 1);
 	      mtr_report("Too many tests($num_failed_test) failed!",
 			 "Terminating...");
 	      return undef;
@@ -640,9 +649,9 @@ sub run_test_server ($$$) {
 	    next;
 	  }
 
-	  # Prefer same configuration
-	  if (defined $result and
-	      $result->{template_path} eq $t->{template_path})
+	  # Prefer same configuration, or just use next if --noreorder
+	  if (!$opt_reorder or (defined $result and
+	      $result->{template_path} eq $t->{template_path}))
 	  {
 	    #mtr_report("Test uses same config => good match");
 	    # Test uses same config => good match
@@ -683,9 +692,9 @@ sub run_test_server ($$$) {
     # ----------------------------------------------------
     # Check if test suite timer expired
     # ----------------------------------------------------
-    if ( ! $suite_timeout_proc->wait_one(0) )
+    if ( has_expired($suite_timeout) )
     {
-      mtr_report_stats($completed, 1);
+      mtr_report_stats("Timeout", $completed, 1);
       mtr_report("Test suite timeout! Terminating...");
       return undef;
     }
@@ -761,6 +770,12 @@ sub run_worker ($) {
     elsif ($line eq 'BYE'){
       mtr_report("Server said BYE");
       stop_all_servers($opt_shutdown_timeout);
+      if ($opt_valgrind_mysqld) {
+        valgrind_exit_reports();
+      }
+      if ( $opt_gprof ) {
+	gprof_collect (find_mysqld($basedir), keys %gprof_dirs);
+      }
       exit(0);
     }
     else {
@@ -841,9 +856,11 @@ sub command_line_setup {
 	     'combination=s'            => \@opt_combinations,
              'skip-combinations'        => \&collect_option,
              'experimental=s'           => \$opt_experimental,
+	     'skip-im'                  => \&ignore_option,
 
              # Specify ports
 	     'build-thread|mtr-build-thread=i' => \$opt_build_thread,
+	     'port-base|mtr-port-base=i'       => \$opt_port_base,
 
              # Test case authoring
              'record'                   => \$opt_record,
@@ -874,6 +891,7 @@ sub command_line_setup {
 
              # Coverage, profiling etc
              'gcov'                     => \$opt_gcov,
+             'gprof'                    => \$opt_gprof,
              'valgrind|valgrind-all'    => \$opt_valgrind,
              'valgrind-mysqltest'       => \$opt_valgrind_mysqltest,
              'valgrind-mysqld'          => \$opt_valgrind_mysqld,
@@ -904,7 +922,7 @@ sub command_line_setup {
              'report-features'          => \$opt_report_features,
              'comment=s'                => \$opt_comment,
              'fast'                     => \$opt_fast,
-             'reorder!'                 => \&collect_option,
+             'reorder!'                 => \$opt_reorder,
              'enable-disabled'          => \&collect_option,
              'verbose+'                 => \$opt_verbose,
              'verbose-restart'          => \&report_option,
@@ -924,6 +942,7 @@ sub command_line_setup {
              'warnings!'                => \$opt_warnings,
 	     'timestamp'                => \&report_option,
 	     'timediff'                 => \&report_option,
+	     'max-connections=i'        => \$opt_max_connections,
 
              'help|h'                   => \$opt_usage,
              'list-options'             => \$opt_list_options,
@@ -948,6 +967,11 @@ sub command_line_setup {
 
   # Find the absolute path to the test directory
   $glob_mysql_test_dir= cwd();
+  if ($glob_mysql_test_dir =~ / /)
+  {
+    die("Working directory \"$glob_mysql_test_dir\" contains space\n".
+	"Bailing out, cannot function properly with space in path");
+  }
   if (IS_CYGWIN)
   {
     # Use mixed path format i.e c:/path/to/
@@ -1104,6 +1128,21 @@ sub command_line_setup {
     }
   }
 
+  if (IS_WINDOWS and defined $opt_mem) {
+    mtr_report("--mem not supported on Windows, ignored");
+    $opt_mem= undef;
+  }
+
+  if ($opt_port_base ne "auto")
+  {
+    if (my $rem= $opt_port_base % 10)
+    {
+      mtr_warning ("Port base $opt_port_base rounded down to multiple of 10");
+      $opt_port_base-= $rem;
+    }
+    $opt_build_thread= $opt_port_base / 10 - 1000;
+  }
+
   # --------------------------------------------------------------------------
   # Check if we should speed up tests by trying to run on tmpfs
   # --------------------------------------------------------------------------
@@ -1276,7 +1315,7 @@ sub command_line_setup {
   # --------------------------------------------------------------------------
   # Gcov flag
   # --------------------------------------------------------------------------
-  if ( $opt_gcov and ! $source_dist )
+  if ( ($opt_gcov or $opt_gprof) and ! $source_dist )
   {
     mtr_error("Coverage test needs the source - please use source dist");
   }
@@ -1375,8 +1414,7 @@ sub command_line_setup {
     push(@valgrind_args, @default_valgrind_args)
       unless @valgrind_args;
 
-    # Make valgrind run in quiet mode so it only print errors
-    push(@valgrind_args, "--quiet" );
+    # Don't add --quiet; you will loose the summary reports.
 
     mtr_report("Running valgrind with options \"",
 	       join(" ", @valgrind_args), "\"");
@@ -1481,6 +1519,12 @@ sub collect_mysqld_features {
   mtr_add_arg($args, "--verbose");
   mtr_add_arg($args, "--help");
 
+  # Need --user=root if running as *nix root user
+  if (!IS_WINDOWS and $> == 0)
+  {
+    mtr_add_arg($args, "--user=root");
+  }
+
   my $exe_mysqld= find_mysqld($basedir);
   my $cmd= join(" ", $exe_mysqld, @$args);
   my $list= `$cmd`;
@@ -1824,11 +1868,11 @@ sub environment_setup {
     {
       push(@ld_library_paths, "$basedir/libmysql/.libs/",
 	   "$basedir/libmysql_r/.libs/",
-	   "$basedir/zlib.libs/");
+	   "$basedir/zlib/.libs/");
     }
     else
     {
-      push(@ld_library_paths, "$basedir/lib");
+      push(@ld_library_paths, "$basedir/lib", "$basedir/lib/mysql");
     }
   }
 
@@ -2601,6 +2645,7 @@ sub create_config_file_for_extern {
 # binlog reads from [client] and [mysqlbinlog]
 [mysqlbinlog]
 character-sets-dir= $path_charsetsdir
+local-load= $opt_tmpdir
 
 # mysql_fix_privilege_tables.sh don't read from [client]
 [mysql_fix_privilege_tables]
@@ -3030,11 +3075,11 @@ sub check_testcase($$)
   # Return immediately if no check proceess was started
   return 0 unless ( keys %started );
 
-  my $timeout_proc= My::SafeProcess->timer(check_timeout());
+  my $timeout= start_timer(check_timeout());
 
   while (1){
     my $result;
-    my $proc= My::SafeProcess->wait_any();
+    my $proc= My::SafeProcess->wait_any_timeout($timeout);
     mtr_report("Got $proc");
 
     if ( delete $started{$proc->pid()} ) {
@@ -3058,9 +3103,6 @@ sub check_testcase($$)
 
 	if ( keys(%started) == 0){
 	  # All checks completed
-
-	  $timeout_proc->kill();
-
 	  return 0;
 	}
 	# Wait for next process to exit
@@ -3101,10 +3143,9 @@ test case was executed:\n";
 
       }
     }
-    elsif ( $proc eq $timeout_proc ) {
-      $tinfo->{comment}.= "Timeout $timeout_proc for ".
-	"'check-testcase' expired after ".check_timeout().
-	  " seconds";
+    elsif ( $proc->{timeout} ) {
+      $tinfo->{comment}.= "Timeout for 'check-testcase' expired after "
+	.check_timeout()." seconds";
       $result= 4;
     }
     else {
@@ -3119,8 +3160,6 @@ test case was executed:\n";
     # Kill any check processes still running
     map($_->kill(), values(%started));
 
-    $timeout_proc->kill();
-
     return $result;
   }
 
@@ -3192,11 +3231,11 @@ sub run_on_all($$)
   # Return immediately if no check proceess was started
   return 0 unless ( keys %started );
 
-  my $timeout_proc= My::SafeProcess->timer(check_timeout());
+  my $timeout= start_timer(check_timeout());
 
   while (1){
     my $result;
-    my $proc= My::SafeProcess->wait_any();
+    my $proc= My::SafeProcess->wait_any_timeout($timeout);
     mtr_report("Got $proc");
 
     if ( delete $started{$proc->pid()} ) {
@@ -3215,17 +3254,15 @@ sub run_on_all($$)
 
       if ( keys(%started) == 0){
 	# All completed
-	$timeout_proc->kill();
 	return 0;
       }
 
       # Wait for next process to exit
       next;
     }
-    elsif ( $proc eq $timeout_proc ) {
-      $tinfo->{comment}.= "Timeout $timeout_proc for '$run' ".
-	"expired after ". check_timeout().
-	  " seconds";
+    elsif ($proc->{timeout}) {
+      $tinfo->{comment}.= "Timeout for '$run' expired after "
+	.check_timeout()." seconds";
     }
     else {
       # Unknown process returned, most likley a crash, abort everything
@@ -3237,8 +3274,6 @@ sub run_on_all($$)
     # Kill any check processes still running
     map($_->kill(), values(%started));
 
-    $timeout_proc->kill();
-
     return 1;
   }
   mtr_error("INTERNAL_ERROR: run_on_all");
@@ -3345,9 +3380,11 @@ sub run_testcase ($) {
 
   mtr_verbose("Running test:", $tinfo->{name});
 
-  # Allow only alpanumerics pluss _ - + . in combination names
+  # Allow only alpanumerics pluss _ - + . in combination names,
+  # or anything beginning with -- (the latter comes from --combination)
   my $combination= $tinfo->{combination};
-  if ($combination && $combination !~ /^\w[-\w\.\+]+$/)
+  if ($combination && $combination !~ /^\w[-\w\.\+]+$/
+                   && $combination !~ /^--/)
   {
     mtr_error("Combination '$combination' contains illegal characters");
   }
@@ -3468,7 +3505,7 @@ sub run_testcase ($) {
     }
   }
 
-  my $test_timeout_proc= My::SafeProcess->timer(testcase_timeout());
+  my $test_timeout= start_timer(testcase_timeout());
 
   do_before_run_mysqltest($tinfo);
 
@@ -3476,9 +3513,6 @@ sub run_testcase ($) {
     # Failed to record state of server or server crashed
     report_failure_and_restart($tinfo);
 
-    # Stop the test case timer
-    $test_timeout_proc->kill();
-
     return 1;
   }
 
@@ -3496,20 +3530,20 @@ sub run_testcase ($) {
       if ($proc)
       {
 	mtr_verbose ("Found exited process $proc");
-	# If that was the timeout, cancel waiting
-	if ( $proc eq $test_timeout_proc )
-	{
-	  $keep_waiting_proc = 0;
-	}
       }
       else
       {
 	$proc = $keep_waiting_proc;
+	# Also check if timer has expired, if so cancel waiting
+	if ( has_expired($test_timeout) )
+	{
+	  $keep_waiting_proc = 0;
+	}
       }
     }
-    else
+    if (! $keep_waiting_proc)
     {
-      $proc= My::SafeProcess->wait_any();
+      $proc= My::SafeProcess->wait_any_timeout($test_timeout);
     }
 
     # Will be restored if we need to keep waiting
@@ -3526,9 +3560,6 @@ sub run_testcase ($) {
     # ----------------------------------------------------
     if ($proc eq $test)
     {
-      # Stop the test case timer
-      $test_timeout_proc->kill();
-
       my $res= $test->exit_status();
 
       if ($res == 0 and $opt_warnings and check_warnings($tinfo) )
@@ -3585,6 +3616,14 @@ sub run_testcase ($) {
 	  run_on_all($tinfo, "analyze-$analyze");
 	}
 
+	# Wait a bit and see if a server died, if so report that instead
+	mtr_milli_sleep(100);
+	my $srvproc= My::SafeProcess::check_any();
+	if ($srvproc && grep($srvproc eq $_, started(all_servers()))) {
+	  $proc= $srvproc;
+	  goto SRVDIED;
+	}
+
 	# Test case failure reported by mysqltest
 	report_failure_and_restart($tinfo);
       }
@@ -3592,7 +3631,7 @@ sub run_testcase ($) {
       {
 	# mysqltest failed, probably crashed
 	$tinfo->{comment}=
-	  "mysqltest failed with unexpected return code $res";
+	  "mysqltest failed with unexpected return code $res\n";
 	report_failure_and_restart($tinfo);
       }
 
@@ -3610,6 +3649,7 @@ sub run_testcase ($) {
     # ----------------------------------------------------
     # Check if it was an expected crash
     # ----------------------------------------------------
+    SRVDIED:
     my $check_crash = check_expected_crash_and_restart($proc);
     if ($check_crash)
     {
@@ -3622,7 +3662,7 @@ sub run_testcase ($) {
     # ----------------------------------------------------
     # Stop the test case timer
     # ----------------------------------------------------
-    $test_timeout_proc->kill();
+    $test_timeout= 0;
 
     # ----------------------------------------------------
     # Check if it was a server that died
@@ -3661,7 +3701,7 @@ sub run_testcase ($) {
     # ----------------------------------------------------
     # Check if testcase timer expired
     # ----------------------------------------------------
-    if ( $proc eq $test_timeout_proc )
+    if ( $proc->{timeout} )
     {
       my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log";
       $tinfo->{comment}=
@@ -3783,16 +3823,24 @@ sub extract_warning_lines ($$) {
     (
      qr/^Warning:|mysqld: Warning|\[Warning\]/,
      qr/^Error:|\[ERROR\]/,
-     qr/^==\d*==/, # valgrind errors
+     qr/^==\d+==\s+\S/, # valgrind errors
      qr/InnoDB: Warning|InnoDB: Error/,
      qr/^safe_mutex:|allocated at line/,
      qr/missing DBUG_RETURN/,
      qr/Attempting backtrace/,
      qr/Assertion .* failed/,
     );
+  my $skip_valgrind= 0;
 
   foreach my $line ( @lines )
   {
+    if ($opt_valgrind_mysqld) {
+      # Skip valgrind summary from tests where server has been restarted
+      # Should this contain memory leaks, the final report will find it
+      $skip_valgrind= 1 if $line =~ /^==\d+== ERROR SUMMARY:/;
+      $skip_valgrind= 0 unless $line =~ /^==\d+==/;
+      next if $skip_valgrind;
+    }
     foreach my $pat ( @patterns )
     {
       if ( $line =~ /$pat/ )
@@ -3832,7 +3880,6 @@ sub start_check_warnings ($$) {
 
   mtr_add_arg($args, "--loose-skip-safemalloc");
   mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test");
-  mtr_add_arg($args, "--verbose");
 
   if ( $opt_embedded_server )
   {
@@ -3895,11 +3942,11 @@ sub check_warnings ($) {
   # Return immediately if no check proceess was started
   return 0 unless ( keys %started );
 
-  my $timeout_proc= My::SafeProcess->timer(check_timeout());
+  my $timeout= start_timer(check_timeout());
 
   while (1){
     my $result= 0;
-    my $proc= My::SafeProcess->wait_any();
+    my $proc= My::SafeProcess->wait_any_timeout($timeout);
     mtr_report("Got $proc");
 
     if ( delete $started{$proc->pid()} ) {
@@ -3928,9 +3975,6 @@ sub check_warnings ($) {
 
 	if ( keys(%started) == 0){
 	  # All checks completed
-
-	  $timeout_proc->kill();
-
 	  return $result;
 	}
 	# Wait for next process to exit
@@ -3947,10 +3991,9 @@ sub check_warnings ($) {
 	$result= 2;
       }
     }
-    elsif ( $proc eq $timeout_proc ) {
-      $tinfo->{comment}.= "Timeout $timeout_proc for ".
-	"'check warnings' expired after ".check_timeout().
-	  " seconds";
+    elsif ( $proc->{timeout} ) {
+      $tinfo->{comment}.= "Timeout for 'check warnings' expired after "
+	.check_timeout()." seconds";
       $result= 4;
     }
     else {
@@ -3964,8 +4007,6 @@ sub check_warnings ($) {
     # Kill any check processes still running
     map($_->kill(), values(%started));
 
-    $timeout_proc->kill();
-
     return $result;
   }
 
@@ -3983,7 +4024,7 @@ sub check_expected_crash_and_restart {
 
   foreach my $mysqld ( mysqlds() )
   {
-    next unless ( $mysqld->{proc} eq $proc );
+    next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc );
 
     # Check if crash expected by looking at the .expect file
     # in var/tmp
@@ -4181,6 +4222,20 @@ sub report_failure_and_restart ($) {
 	# about what failed has been saved to file. Save the report
 	# in tinfo
 	$tinfo->{logfile}= mtr_fromfile($logfile);
+	# If no newlines in the test log:
+	# (it will contain the CURRENT_TEST written by mtr, so is not empty)
+	if ($tinfo->{logfile} !~ /\n/)
+	{
+	  # Show how far it got before suddenly failing
+	  $tinfo->{comment}.= "mysqltest failed but provided no output\n";
+	  my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log";
+	  if (-e $log_file_name) {
+	    $tinfo->{comment}.=
+	      "The result from queries just before the failure was:".
+	      "\n< snip >\n".
+	      mtr_lastlinesfromfile($log_file_name, 20)."\n";
+	  }
+	}
       }
       else
       {
@@ -4395,6 +4450,10 @@ sub mysqld_start ($$) {
     # see the exact location where valgrind complains
     $output= "$opt_vardir/log/".$mysqld->name().".trace";
   }
+  # Remember this log file for valgrind error report search
+  $mysqld_logs{$output}= 1 if $opt_valgrind;
+  # Remember data dir for gmon.out files if using gprof
+  $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof;
 
   if ( defined $exe )
   {
@@ -4944,6 +5003,10 @@ sub start_mysqltest ($) {
     mtr_add_arg($args, "--ssl");
   }
 
+  if ( $opt_max_connections ) {
+    mtr_add_arg($args, "--max-connections=%d", $opt_max_connections);
+  }
+
   if ( $opt_embedded_server )
   {
 
@@ -5172,7 +5235,7 @@ sub debugger_arguments {
   {
     # vc[express] /debugexe exe arg1 .. argn
 
-    # Add /debugexe and name of the exe before args
+    # Add name of the exe and /debugexe before args
     unshift(@$$args, "$$exe");
     unshift(@$$args, "/debugexe");
 
@@ -5247,6 +5310,66 @@ sub valgrind_arguments {
   }
 }
 
+#
+# Search server logs for valgrind reports printed at mysqld termination
+#
+
+sub valgrind_exit_reports() {
+  foreach my $log_file (keys %mysqld_logs)
+  {
+    my @culprits= ();
+    my $valgrind_rep= "";
+    my $found_report= 0;
+    my $err_in_report= 0;
+
+    my $LOGF = IO::File->new($log_file)
+      or mtr_error("Could not open file '$log_file' for reading: $!");
+
+    while ( my $line = <$LOGF> )
+    {
+      if ($line =~ /^CURRENT_TEST: (.+)$/)
+      {
+        my $testname= $1;
+        # If we have a report, report it if needed and start new list of tests
+        if ($found_report)
+        {
+          if ($err_in_report)
+          {
+            mtr_print ("Valgrind report from $log_file after tests:\n",
+                        @culprits);
+            mtr_print_line();
+            print ("$valgrind_rep\n");
+            $err_in_report= 0;
+          }
+          # Make ready to collect new report
+          @culprits= ();
+          $found_report= 0;
+          $valgrind_rep= "";
+        }
+        push (@culprits, $testname);
+        next;
+      }
+      # This line marks the start of a valgrind report
+      $found_report= 1 if $line =~ /ERROR SUMMARY:/;
+
+      if ($found_report) {
+        $line=~ s/^==\d+== //;
+        $valgrind_rep .= $line;
+        $err_in_report= 1 if $line =~ /ERROR SUMMARY: [1-9]/;
+        $err_in_report= 1 if $line =~ /definitely lost: [1-9]/;
+        $err_in_report= 1 if $line =~ /possibly lost: [1-9]/;
+      }
+    }
+
+    $LOGF= undef;
+
+    if ($err_in_report) {
+      mtr_print ("Valgrind report from $log_file after tests:\n", @culprits);
+      mtr_print_line();
+      print ("$valgrind_rep\n");
+    }
+  }
+}
 
 #
 # Usage
@@ -5326,6 +5449,11 @@ Options to control what test suites or cases to run
 
 Options that specify ports
 
+  mtr-port-base=#       Base for port numbers, ports from this number to
+  port-base=#           number+9 are reserved. Should be divisible by 10;
+                        if not it will be rounded down. May be set with
+                        environment variable MTR_PORT_BASE. If this value is
+                        set and is not "auto", it overrides build-thread.
   mtr-build-thread=#    Specify unique number to calculate port number(s) from.
   build-thread=#        Can be set in environment variable MTR_BUILD_THREAD.
                         Set  MTR_BUILD_THREAD="auto" to automatically aquire
@@ -5437,6 +5565,7 @@ Misc options
   timestamp             Print timestamp before each test report line
   timediff              With --timestamp, also print time passed since
                         *previous* test started
+  max-connections=N     Max number of open connection to server in mysqltest
 
 HERE
   exit(1);
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 2e3a9489593..67c08b0ae97 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -147,9 +147,10 @@ hello
 hello
 ;;;;;;;;
 # MySQL: -- The
-mysqltest: At line 1: End of line junk detected: "6"
-mysqltest: At line 1: End of line junk detected: "6"
-mysqltest: At line 1: Missing delimiter
+mysqltest: At line 1: Extra argument '6' passed to 'sleep'
+mysqltest: At line 1: Extra argument '6' passed to 'sleep'
+mysqltest: At line 1: Extra argument 'A comment
+show status' passed to 'sleep'
 mysqltest: At line 1: End of line junk detected: "sleep 7
 # Another comment
 "
@@ -216,6 +217,12 @@ source database
 echo message echo message
 
 mysqltest: At line 1: Missing argument in exec
+1
+1
+2
+2
+X
+3
 MySQL
 "MySQL"
 MySQL: The
@@ -348,8 +355,10 @@ here is the sourced script
 here is the sourced script
 "hello"
 "hello"
-mysqltest: At line 1: Missing argument to sleep
-mysqltest: At line 1: Missing argument to real_sleep
+mysqltest: At line 2: Invalid argument to sleep "xyz"
+mysqltest: At line 2: Invalid argument to real_sleep "xyz"
+mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'sleep'
+mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'real_sleep'
 mysqltest: At line 1: Invalid argument to sleep "abc"
 mysqltest: At line 1: Invalid argument to real_sleep "abc"
 1
@@ -377,6 +386,10 @@ test
 test2
 test3
 test4
+outer
+true-inner
+true-inner again
+true-outer
 Counter is greater than 0, (counter=10)
 Counter is not 0, (counter=0)
 1
@@ -417,6 +430,9 @@ mysqltest: At line 1: Wrong number of arguments to replace_column in 'replace_co
 mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a b'
 mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a 1'
 mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 b c '
+select "LONG_STRING" as x;
+x
+LONG_STRING
 mysqltest: At line 1: Invalid integer argument "10!"
 mysqltest: At line 1: Invalid integer argument "a"
 mysqltest: At line 1: Missing required argument 'connection name' to command 'connect'
@@ -523,7 +539,28 @@ a	D
 1	1
 1	4
 drop table t1;
+create table t1 ( f1 char(10));
+insert into t1 values ("Abcd");
+select * from t1;
+f1
+Abcd
+select * from t2;;
+ERROR 42S02: Table 'test.t2' doesn't exist
+select * from t1;
+f1
+Abcd
+select * from t1;;
+Result coming up
+f1
+Abcd
+select * from t1;;
+f1
+Abcd
+mysqltest: At line 2: Cannot run query on connection between send and reap
+select * from t1;;
+drop table t1;
 mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file'
+mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard'
 mysqltest: At line 1: Missing required argument 'filename' to command 'write_file'
 mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found
 Content for test_file1
@@ -553,6 +590,8 @@ hello
 mysqltest: At line 1: Max delimiter length(16) exceeded
 hello
 hello
+val is 5
+val is 5
 mysqltest: At line 1: test of die
 Some output
 create table t1( a int, b char(255), c timestamp);
@@ -680,6 +719,29 @@ INSERT INTO t1 SELECT f1 - 256 FROM t1;
 INSERT INTO t1 SELECT f1 - 512 FROM t1;
 SELECT * FROM t1;
 DROP TABLE t1;
+select "500g bl�b�rsyltet�y" as "will be lower cased";
+will be lower cased
+500g bl�b�rsyltet�y
+SELECT "UPPER" AS "WILL NOT BE lower cased";
+WILL NOT BE lower cased
+UPPER
+UP
+SELECT 0 as "UP AGAIN";
+UP AGAIN
+0
+select "abcdef" as "uvwxyz";
+uvwxyz
+abcdef
+select "xyz" as name union select "abc" as name order by name desc;
+name
+abc
+xyz
+select 1 as "some new text";
+some new text
+1
+select 0 as "will not lower case ���";
+will not lower case ���
+0
 CREATE TABLE t1(
 a int, b varchar(255), c datetime
 );
@@ -726,6 +788,8 @@ mysqltest: At line 1: change user failed: Access denied for user 'root'@'localho
 file1.txt
 file1.txt
 file2.txt
+file11.txt
+dir-list.txt
 SELECT 'c:\\a.txt' AS col;
 col
 z
diff --git a/mysql-test/r/variables+c.result b/mysql-test/r/variables_community.result
similarity index 100%
rename from mysql-test/r/variables+c.result
rename to mysql-test/r/variables_community.result
diff --git a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test
index 6638a20c926..330addd6b3b 100644
--- a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test
+++ b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test
@@ -78,6 +78,7 @@ COMMIT;
 
 --echo 'CONNECTION con2'
 CONNECTION con2;
+reap;
 UNLOCK tables;
 
 DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
index 87813a958e0..03f56f1fe16 100644
--- a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
+++ b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test
@@ -128,6 +128,7 @@ connection con0;
 SET SESSION low_priority_updates = OFF;
 --echo ** Connection con1 **
 connection con1;
+reap;
 SET SESSION low_priority_updates = OFF;
 --echo ** Connection default**
 connection default;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index bcf33aa8c27..25293ff29e7 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -605,6 +605,15 @@ echo ;
 --error 1
 --exec echo "--exec " | $MYSQL_TEST 2>&1
 
+# Multi-line exec
+exec $MYSQL
+    test -e "select 1";
+exec $MYSQL test -e "select
+    2";
+let $query = select 3
+    as X;
+exec $MYSQL test -e "$query";
+
 # ----------------------------------------------------------------------------
 # Test let command
 # ----------------------------------------------------------------------------
@@ -911,6 +920,28 @@ sleep 0.5;
 sleep 1;
 real_sleep 1;
 
+# Parameter from variable, legal and illegal
+let $sleep_var= 0.1;
+sleep $sleep_var;
+let $sleep_var= 1;
+--real_sleep $sleep_var
+
+--write_file $MYSQL_TMP_DIR/sleep.inc
+let $sleep_var= xyz;
+--sleep $sleep_var
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1
+--remove_file $MYSQL_TMP_DIR/sleep.inc
+
+--write_file $MYSQL_TMP_DIR/sleep.inc
+let $sleep_var= xyz;
+real_sleep $sleep_var;
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1
+--remove_file $MYSQL_TMP_DIR/sleep.inc
+
 # Missing parameter
 --error 1
 --exec echo "sleep ;" | $MYSQL_TEST 2>&1
@@ -1006,6 +1037,37 @@ echo test3stop
 --delimiter ;
 echo test4;
 
+# ----------------------------------------------------------------------------
+# Test that delimiter within if() works in in various combinations
+# ----------------------------------------------------------------------------
+
+if (0)
+{
+  delimiter ||;
+  echo false-inner||
+  if (0)
+  {
+    delimiter *||
+    echo false-innerer*
+    delimiter ||*
+  }
+  echo false-inner again||
+}
+echo outer;
+if (1)
+{
+  delimiter /;
+  echo true-inner/
+  if (0)
+  {
+    delimiter %/
+    echo true-innerer%
+  }
+  echo true-inner again/
+}
+echo true-outer/
+delimiter ;/
+
 
 # ----------------------------------------------------------------------------
 # Test if
@@ -1285,6 +1347,17 @@ select "a" as col1, "c" as col2;
 --error 1
 --exec echo "--replace_column 1 b c " | $MYSQL_TEST 2>&1
 
+let $long_rep= 1234567890123456789012345678901234567890;
+let $long_rep= $long_rep,$long_rep;
+let $long_rep= $long_rep,$long_rep;
+let $long_rep= $long_rep,$long_rep;
+let $long_rep= $long_rep,$long_rep;
+let $long_rep= $long_rep,$long_rep;
+
+# This tests from strings > 1024 (here 1311)
+
+--replace_result $long_rep LONG_STRING
+eval select "$long_rep" as x;
 
 # ----------------------------------------------------------------------------
 # Test sync_with_master
@@ -1605,6 +1678,57 @@ insert into t1 values (2,4);
 select * from t1;
 drop table t1;
 
+# ----------------------------------------------------------------------------
+# Tests of send
+# ----------------------------------------------------------------------------
+
+create table t1 ( f1 char(10));
+insert into t1 values ("Abcd");
+
+# 1. Basic test
+
+send select * from t1;
+reap;
+
+# 2. Test with error
+
+--send select * from t2;
+--error ER_NO_SUCH_TABLE
+--reap
+
+# 3. test send of next stmt
+
+--send
+select * from t1;
+--reap
+
+# 4. Non-query stmt betwen send and reap allowed
+
+--send select * from t1;
+--sleep 0.05
+--echo Result coming up
+--reap
+
+# 5. Test of send_eval
+
+--let $my_stmt= select * from t1;
+--send_eval $my_stmt
+--reap
+
+# 6. Test that mysqltest does not allow query stmt between send and reap
+# Untestable directly as it causes mysqltest to fail
+
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.in
+--send select * from t1;
+select 1;
+--reap
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.in;
+
+drop table t1;
+
 # ----------------------------------------------------------------------------
 # test for remove_file
 # ----------------------------------------------------------------------------
@@ -1615,6 +1739,19 @@ drop table t1;
 --error 1
 remove_file non_existing_file;
 
+# ----------------------------------------------------------------------------
+# test for remove_files_wildcard
+# ----------------------------------------------------------------------------
+
+--error 1
+--exec echo "remove_files_wildcard ;" | $MYSQL_TEST 2>&1
+
+--error 1
+remove_files_wildcard non_existing_dir;
+
+--error 1
+remove_files_wildcard non_existing_dir non_existing_file;
+
 # ----------------------------------------------------------------------------
 # test for write_file
 # ----------------------------------------------------------------------------
@@ -1905,6 +2042,20 @@ perl;
   print "hello\n";
 EOF
 
+# Test perl within while, also with if being false first iteration
+let $outer= 3;
+let $ifval= 0;
+while ($outer) {
+  if ($ifval) {
+    perl UNTIL;
+      my $val= 5;
+      print "val is $val\n";
+UNTIL
+  }
+  inc $ifval;
+  dec $outer;
+}
+
 # ----------------------------------------------------------------------------
 # test for die
 # ----------------------------------------------------------------------------
@@ -2045,6 +2196,44 @@ INSERT INTO t1 SELECT f1 - 512 FROM t1;
 SELECT * FROM t1;
 --enable_result_log
 DROP TABLE t1;
+
+# ----------------------------------------------------------------------------
+# test for lowercase_result
+# ----------------------------------------------------------------------------
+
+# 1. Basic test
+--lowercase_result
+SELECT "500g BL�B�RSYLTET�Y" AS "WILL BE lower cased";
+
+# 2. test that it does not apply to next statement
+SELECT "UPPER" AS "WILL NOT BE lower cased";
+
+# 3. test that it does not affect non-SQL or the following statement
+--lowercase_result
+--echo UP
+SELECT 0 as "UP AGAIN";
+
+# 4. test that it works with eval and variables
+let $lower_stmt=SELECT "ABCdef" AS "uvwXYZ";
+--lowercase_result
+eval $lower_stmt;
+
+# 5. test that it works in combination with sort
+sorted_result;
+lowercase_result;
+SELECT "Xyz" AS Name UNION SELECT "Abc" as Name ORDER BY Name DESC;
+
+# 6. Test combination with replace, and that lower casing is done first
+--lowercase_result
+--replace_result old new
+SELECT 1 as "SOME OLD TEXT";
+
+# 7. Test missing lower casing of "unknown" characters
+--character_set utf8
+--lowercase_result
+SELECT 0 as "WILL NOT lower case ���";
+--character_set latin1
+
 # ----------------------------------------------------------------------------
 # Some coverage tests
 # ----------------------------------------------------------------------------
@@ -2230,9 +2419,14 @@ rmdir $MYSQLTEST_VARDIR/tmp/testdir;
 
 cat_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt;
 
-remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt;
-remove_file $MYSQLTEST_VARDIR/tmp/testdir/file2.txt;
-remove_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt;
+list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/file11.txt $MYSQLTEST_VARDIR/tmp/testdir file?.txt;
+remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file?.txt;
+list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt $MYSQLTEST_VARDIR/tmp/testdir file*.txt;
+cat_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt;
+remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file*.txt;
+list_files $MYSQLTEST_VARDIR/tmp/testdir;
+remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir;
+list_files $MYSQLTEST_VARDIR/tmp/testdir;
 rmdir $MYSQLTEST_VARDIR/tmp/testdir;
 
 #
diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test
index 2bf879603a4..294521a45d5 100644
--- a/mysql-test/t/partition_innodb_semi_consistent.test
+++ b/mysql-test/t/partition_innodb_semi_consistent.test
@@ -187,6 +187,7 @@ SELECT * FROM t1;
 
 --echo # Switch to connection con2
 connection con2;
+reap;
 SELECT * FROM t1;
 
 connection default;
diff --git a/mysql-test/t/variables+c.test b/mysql-test/t/variables_community.test
similarity index 100%
rename from mysql-test/t/variables+c.test
rename to mysql-test/t/variables_community.test
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index b4cfc054b35..be594b42ea2 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -416,8 +416,7 @@ else
   echo "Try 'mysqld --help' if you have problems with paths.  Using --log"
   echo "gives you a log in $ldata that may be helpful."
   echo
-  echo "The latest information about MySQL is available on the web at"
-  echo "http://www.mysql.com/.  Please consult the MySQL manual section"
+  echo "Please consult the MySQL manual section"
   echo "'Problems running mysql_install_db', and the manual section that"
   echo "describes problems on your OS.  Another information source are the"
   echo "MySQL email archives available at http://lists.mysql.com/."
@@ -476,9 +475,6 @@ then
   echo
   echo "Please report any problems with the $scriptdir/mysqlbug script!"
   echo
-  echo "The latest information about MySQL is available at http://www.mysql.com/"
-  echo "Support MySQL by buying support/licenses from http://shop.mysql.com/"
-  echo
 fi
 
 exit 0