diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 58ba1cb..65adc63 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -124,6 +124,10 @@ static char *inferior_io_terminal_scratch;

 ptid_t inferior_ptid;

+/* See inferior.h.  */
+
+int command_changes_user_selected_ptid;
+
 /* Address at which inferior stopped.  */

 CORE_ADDR stop_pc;
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 571d26a..edf829e 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -82,6 +82,11 @@ extern const char *get_inferior_io_terminal (void);

 extern ptid_t inferior_ptid;

+/* Flag indicating that we explicitly want to change the user selected
+   thread/ptid.  */
+
+extern int command_changes_user_selected_ptid;
+
 extern void generic_mourn_inferior (void);

 extern CORE_ADDR unsigned_pointer_to_address (struct gdbarch *gdbarch,
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index b1cbd8b..0933615 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2163,18 +2163,9 @@ mi_execute_command (const char *cmd, int from_tty)
 	    = (struct mi_interp *) top_level_interpreter_data ();
 	  int report_change = 0;

-	  if (command->thread == -1)
-	    {
-	      report_change = (!ptid_equal (previous_ptid, null_ptid)
-			       && !ptid_equal (inferior_ptid, previous_ptid)
-			       && !ptid_equal (inferior_ptid, null_ptid));
-	    }
-	  else if (!ptid_equal (inferior_ptid, null_ptid))
-	    {
-	      struct thread_info *ti = inferior_thread ();
-
-	      report_change = (ti->global_num != command->thread);
-	    }
+	  report_change = (!ptid_equal (previous_ptid, null_ptid)
+			   && !ptid_equal (inferior_ptid, previous_ptid)
+			   && !ptid_equal (inferior_ptid, null_ptid));

 	  if (report_change)
 	    {
@@ -2201,6 +2192,7 @@ static void
 mi_cmd_execute (struct mi_parse *parse)
 {
   struct cleanup *cleanup;
+  struct cleanup *thread_restore_cleanup = NULL;

   cleanup = prepare_execute_command ();

@@ -2216,6 +2208,18 @@ mi_cmd_execute (struct mi_parse *parse)
   if (parse->frame != -1 && parse->thread == -1)
     error (_("Cannot specify --frame without --thread"));

+  if (parse->language != language_unknown)
+    {
+      make_cleanup_restore_current_language ();
+      set_language (parse->language);
+    }
+
+  if (parse->cmd->suppress_notification != NULL)
+    {
+      make_cleanup_restore_integer (parse->cmd->suppress_notification);
+      *parse->cmd->suppress_notification = 1;
+    }
+
   if (parse->thread_group != -1)
     {
       struct inferior *inf = find_inferior_id (parse->thread_group);
@@ -2224,6 +2228,8 @@ mi_cmd_execute (struct mi_parse *parse)
       if (!inf)
 	error (_("Invalid thread group for the --thread-group option"));

+      thread_restore_cleanup = make_cleanup_restore_current_thread ();
+
       set_current_inferior (inf);
       /* This behaviour means that if --thread-group option identifies
 	 an inferior with multiple threads, then a random one will be
@@ -2246,6 +2252,8 @@ mi_cmd_execute (struct mi_parse *parse)
       if (is_exited (tp->ptid))
 	error (_("Thread id: %d has terminated"), parse->thread);

+      thread_restore_cleanup = make_cleanup_restore_current_thread ();
+
       switch_to_thread (tp->ptid);
     }

@@ -2262,20 +2270,8 @@ mi_cmd_execute (struct mi_parse *parse)
 	error (_("Invalid frame id: %d"), frame);
     }

-  if (parse->language != language_unknown)
-    {
-      make_cleanup_restore_current_language ();
-      set_language (parse->language);
-    }
-
   current_context = parse;

-  if (parse->cmd->suppress_notification != NULL)
-    {
-      make_cleanup_restore_integer (parse->cmd->suppress_notification);
-      *parse->cmd->suppress_notification = 1;
-    }
-
   if (parse->cmd->argv_func != NULL)
     {
       parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
@@ -2302,6 +2298,10 @@ mi_cmd_execute (struct mi_parse *parse)
       make_cleanup_ui_file_delete (stb);
       error_stream (stb);
     }
+
+  if (command_changes_user_selected_ptid && thread_restore_cleanup != NULL)
+    discard_cleanups (thread_restore_cleanup);
+
   do_cleanups (cleanup);
 }

diff --git a/gdb/thread.c b/gdb/thread.c
index ab98777..7aa1ce7 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -2055,6 +2055,7 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
     error (_("Thread ID %s has terminated."), tidstr);

   switch_to_thread (tp->ptid);
+  command_changes_user_selected_ptid = 1;

   annotate_thread_changed ();

diff --git a/gdb/top.c b/gdb/top.c
index 36c300e..79b1ad6 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -503,6 +503,7 @@ prepare_execute_command (void)

   mark = value_mark ();
   cleanup = make_cleanup_value_free_to_mark (mark);
+  command_changes_user_selected_ptid = 0;

   /* With multiple threads running while the one we're examining is
      stopped, the dcache can get stale without us being able to detect
