diff --git a/apps/app_minivm.c b/apps/app_minivm.c
index 789a48aab682d4770974c16198f08843128c791f..da2956f52635b16610351170a97b5cd862d27c4f 100644
--- a/apps/app_minivm.c
+++ b/apps/app_minivm.c
@@ -3016,11 +3016,9 @@ static char *complete_minivm_show_users(const char *line, const char *word, int
 	struct minivm_account *vmu;
 	const char *domain = "";
 
-	/* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
+	/* 0 - minivm; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
 	if (pos > 4)
 		return NULL;
-	if (pos == 3)
-		return (state == 0) ? ast_strdup("for") : NULL;
 	wordlen = strlen(word);
 	AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) {
 		if (!strncasecmp(word, vmu->domain, wordlen)) {
@@ -3042,9 +3040,9 @@ static char *handle_minivm_show_users(struct ast_cli_entry *e, int cmd, struct a
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "minivm list accounts";
+		e->command = "minivm list accounts [for]";
 		e->usage =
-			"Usage: minivm list accounts\n"
+			"Usage: minivm list accounts [for <domain>]\n"
 			"       Lists all mailboxes currently set up\n";
 		return NULL;
 	case CLI_GENERATE:
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 1c75105dd379db8bc8ae7c8bd6e754544d917fca..5e4df8ea4df92faef03030c12472992bbeb2f1ac 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -12668,11 +12668,9 @@ static char *complete_voicemail_show_users(const char *line, const char *word, i
 	struct ast_vm_user *vmu;
 	const char *context = "";
 
-	/* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
+	/* 0 - voicemail; 1 - show; 2 - users; 3 - for; 4 - <context> */
 	if (pos > 4)
 		return NULL;
-	if (pos == 3)
-		return (state == 0) ? ast_strdup("for") : NULL;
 	wordlen = strlen(word);
 	AST_LIST_TRAVERSE(&users, vmu, list) {
 		if (!strncasecmp(word, vmu->context, wordlen)) {
@@ -12695,7 +12693,7 @@ static char *handle_voicemail_show_users(struct ast_cli_entry *e, int cmd, struc
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "voicemail show users";
+		e->command = "voicemail show users [for]";
 		e->usage =
 			"Usage: voicemail show users [for <context>]\n"
 			"       Lists all mailboxes currently set up\n";
diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c
index f5bb7eb57c3099b378128abefc2b12eb35fe56e3..96ed8920c716be286e7014b7e61b694d1f3e865d 100644
--- a/apps/confbridge/conf_config_parser.c
+++ b/apps/confbridge/conf_config_parser.c
@@ -1343,7 +1343,7 @@ static char *handle_cli_confbridge_show_user_profiles(struct ast_cli_entry *e, i
 	case CLI_INIT:
 		e->command = "confbridge show profile users";
 		e->usage =
-			"Usage confbridge show profile users\n";
+			"Usage: confbridge show profile users\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
@@ -1373,7 +1373,7 @@ static char *handle_cli_confbridge_show_user_profile(struct ast_cli_entry *e, in
 	case CLI_INIT:
 		e->command = "confbridge show profile user";
 		e->usage =
-			"Usage confbridge show profile user [<profile name>]\n";
+			"Usage: confbridge show profile user [<profile name>]\n";
 		return NULL;
 	case CLI_GENERATE:
 		if (a->pos == 4) {
@@ -1494,7 +1494,7 @@ static char *handle_cli_confbridge_show_bridge_profiles(struct ast_cli_entry *e,
 	case CLI_INIT:
 		e->command = "confbridge show profile bridges";
 		e->usage =
-			"Usage confbridge show profile bridges\n";
+			"Usage: confbridge show profile bridges\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
@@ -1526,7 +1526,7 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e,
 	case CLI_INIT:
 		e->command = "confbridge show profile bridge";
 		e->usage =
-			"Usage confbridge show profile bridge <profile name>\n";
+			"Usage: confbridge show profile bridge <profile name>\n";
 		return NULL;
 	case CLI_GENERATE:
 		if (a->pos == 4) {
@@ -1668,7 +1668,7 @@ static char *handle_cli_confbridge_show_menus(struct ast_cli_entry *e, int cmd,
 	case CLI_INIT:
 		e->command = "confbridge show menus";
 		e->usage =
-			"Usage confbridge show profile menus\n";
+			"Usage: confbridge show profile menus\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
@@ -1702,7 +1702,7 @@ static char *handle_cli_confbridge_show_menu(struct ast_cli_entry *e, int cmd, s
 	case CLI_INIT:
 		e->command = "confbridge show menu";
 		e->usage =
-			"Usage confbridge show menu [<menu name>]\n";
+			"Usage: confbridge show menu [<menu name>]\n";
 		return NULL;
 	case CLI_GENERATE:
 		if (a->pos == 3) {
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 6508a1e07dfa3a272354c2814f1be1ae17a5be52..61ea2e7194b7a838724401db45775c7a3ef4fd16 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -639,29 +639,13 @@ static struct ast_channel *alsa_request(const char *type, struct ast_format_cap
 	return tmp;
 }
 
-static char *autoanswer_complete(const char *line, const char *word, int pos, int state)
-{
-	switch (state) {
-		case 0:
-			if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
-				return ast_strdup("on");
-		case 1:
-			if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
-				return ast_strdup("off");
-		default:
-			return NULL;
-	}
-
-	return NULL;
-}
-
 static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *res = CLI_SUCCESS;
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "console autoanswer";
+		e->command = "console autoanswer [on|off]";
 		e->usage =
 			"Usage: console autoanswer [on|off]\n"
 			"       Enables or disables autoanswer feature.  If used without\n"
@@ -669,7 +653,7 @@ static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli
 			"       The default value of autoanswer is in 'alsa.conf'.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return autoanswer_complete(a->line, a->word, a->pos, a->n);
+		return NULL;
 	}
 
 	if ((a->argc != 2) && (a->argc != 3))
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 83f72b9ade5ba09fa3b34dc64c43e30ac3e3401d..f31302e8bf50e1a25d70b44ceebc39309c503914 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -19527,7 +19527,7 @@ static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "sip show inuse";
+		e->command = "sip show inuse [all]";
 		e->usage =
 			"Usage: sip show inuse [all]\n"
 			"       List all SIP devices usage counters and limits.\n"
@@ -19717,7 +19717,7 @@ static char *sip_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "sip show users";
+		e->command = "sip show users [like]";
 		e->usage =
 			"Usage: sip show users [like <pattern>]\n"
 			"       Lists all known SIP users.\n"
@@ -19856,7 +19856,7 @@ static char *sip_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 {
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "sip show peers";
+		e->command = "sip show peers [like]";
 		e->usage =
 			"Usage: sip show peers [like <pattern>]\n"
 			"       Lists all known SIP peers.\n"
@@ -20570,7 +20570,12 @@ static char *sip_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 			"       Option \"load\" forces lookup of peer in realtime storage.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
+		if (a->pos == 4) {
+			static const char * const completions[] = { "load", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
+		} else {
+			return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
+		}
 	}
 	return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
 }
@@ -20740,7 +20745,12 @@ static char *sip_qualify_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_a
 			"       Option \"load\" forces lookup of peer in realtime storage.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
+		if (a->pos == 4) {
+			static const char * const completions[] = { "load", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
+		} else {
+			return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
+		}
 	}
 	return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
 }
@@ -21111,7 +21121,12 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 			"       Option \"load\" forces lookup of peer in realtime storage.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return complete_sip_show_user(a->line, a->word, a->pos, a->n);
+		if (a->pos == 4) {
+			static const char * const completions[] = { "load", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
+		} else {
+			return complete_sip_show_user(a->line, a->word, a->pos, a->n);
+		}
 	}
 
 	if (a->argc < 4)
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 5cdfe1b782fbfb102cd8a3d536a489f77adf8515..9cde775405ccd9184a75a3d51301366e0bd80a33 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -3924,24 +3924,40 @@ static char *complete_skinny_show_device(const char *line, const char *word, int
 
 static char *complete_skinny_reset(const char *line, const char *word, int pos, int state)
 {
-	return (pos == 2 ? complete_skinny_devices(word, state) : NULL);
+	if (pos == 2) {
+		static const char * const completions[] = { "all", NULL };
+		char *ret = ast_cli_complete(word, completions, state);
+		if (!ret) {
+			ret = complete_skinny_devices(word, state - 1);
+		}
+		return ret;
+	} else if (pos == 3) {
+		static const char * const completions[] = { "restart", NULL };
+		return ast_cli_complete(word, completions, state);
+	}
+
+	return NULL;
 }
 
 static char *complete_skinny_show_line(const char *line, const char *word, int pos, int state)
 {
-	struct skinny_device *d;
-	struct skinny_line *l;
-	int wordlen = strlen(word), which = 0;
+	if (pos == 3) {
+		struct skinny_device *d;
+		struct skinny_line *l;
+		int wordlen = strlen(word), which = 0;
 
-	if (pos != 3)
-		return NULL;
-
-	AST_LIST_TRAVERSE(&devices, d, list) {
-		AST_LIST_TRAVERSE(&d->lines, l, list) {
-			if (!strncasecmp(word, l->name, wordlen) && ++which > state) {
-				return ast_strdup(l->name);
+		AST_LIST_TRAVERSE(&devices, d, list) {
+			AST_LIST_TRAVERSE(&d->lines, l, list) {
+				if (!strncasecmp(word, l->name, wordlen) && ++which > state) {
+					return ast_strdup(l->name);
+				}
 			}
 		}
+	} else if (pos == 4) {
+		static const char * const completions[] = { "on", NULL };
+		return ast_cli_complete(word, completions, state);
+	} else if (pos == 5) {
+		return complete_skinny_devices(word, state);
 	}
 
 	return NULL;
@@ -4583,7 +4599,7 @@ static char *handle_skinny_show_line(struct ast_cli_entry *e, int cmd, struct as
 	case CLI_INIT:
 		e->command = "skinny show line";
 		e->usage =
-			"Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n"
+			"Usage: skinny show line <Line> [on <DeviceID|DeviceName>]\n"
 			"       List all lineinformation of a specific line known to the Skinny subsystem.\n";
 		return NULL;
 	case CLI_GENERATE:
diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c
index e2ca7c823d0b302efc504a67e3df3b90411dbd4a..84b6e686b83a88035126f0cb8db10277be92acb4 100644
--- a/funcs/func_odbc.c
+++ b/funcs/func_odbc.c
@@ -1419,7 +1419,8 @@ static char *cli_odbc_read(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 			AST_RWLIST_UNLOCK(&queries);
 			return NULL;
 		} else if (a->pos == 4) {
-			return a->n == 0 ? ast_strdup("exec") : NULL;
+			static const char * const completions[] = { "exec", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
 		} else {
 			return NULL;
 		}
@@ -1625,7 +1626,8 @@ static char *cli_odbc_write(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 			AST_RWLIST_UNLOCK(&queries);
 			return NULL;
 		} else if (a->pos == 5) {
-			return a->n == 0 ? ast_strdup("exec") : NULL;
+			static const char * const completions[] = { "exec", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
 		} else {
 			return NULL;
 		}
diff --git a/main/asterisk.c b/main/asterisk.c
index 994dfbeb76469988248ab5b4b05dca4841831953..076ae6d224c20da0b61f7a4871f060fbcb9ab56d 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -1064,35 +1064,30 @@ static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_c
 static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT "%-25.25s %-40.40s\n"
+	static const char * const completions[] = { "like", NULL };
 	struct registered_file *iterator;
 	regex_t regexbuf;
 	int havepattern = 0;
 	int havename = 0;
 	int count_files = 0;
 	char *ret = NULL;
-	int matchlen, which = 0;
-	struct registered_file *find;
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "core show file version [like]";
+		e->command = "core show file version";
 		e->usage =
-			"Usage: core show file version [like <pattern>]\n"
+			"Usage: core show file version [<filename>|like <pattern>]\n"
 			"       Lists the files along with the Asterisk version.\n"
 			"       Optional regular expression pattern is used to filter the file list.\n";
 		return NULL;
 	case CLI_GENERATE:
-		matchlen = strlen(a->word);
-		if (a->pos != 3)
+		if (a->pos != 4) {
 			return NULL;
-		AST_RWLIST_RDLOCK(&registered_files);
-		AST_RWLIST_TRAVERSE(&registered_files, find, list) {
-			if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
-				ret = ast_strdup(find->file);
-				break;
-			}
 		}
-		AST_RWLIST_UNLOCK(&registered_files);
+		ret = ast_cli_complete(a->word, completions, a->n);
+		if (!ret) {
+			ret = ast_complete_source_filename(a->word, a->n - 1);
+		}
 		return ret;
 	}
 
@@ -1107,6 +1102,9 @@ static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct
 			return CLI_SHOWUSAGE;
 		break;
 	case 5:
+		if (!strcasecmp(a->argv[4], "like")) {
+			return CLI_SHOWUSAGE;
+		}
 		havename = 1;
 		break;
 	case 4:
diff --git a/main/astmm.c b/main/astmm.c
index 3317784891fa2b96253cab22e77f948d59860986..d53323abad18eac499ad0d21b717cb0ce877d579 100644
--- a/main/astmm.c
+++ b/main/astmm.c
@@ -702,17 +702,12 @@ static char *handle_memory_atexit_list(struct ast_cli_entry *e, int cmd, struct
 {
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "memory atexit list";
+		e->command = "memory atexit list {on|off}";
 		e->usage =
 			"Usage: memory atexit list {on|off}\n"
 			"       Enable dumping a list of still allocated memory segments at exit.\n";
 		return NULL;
 	case CLI_GENERATE:
-		if (a->pos == 3) {
-			const char * const options[] = { "off", "on", NULL };
-
-			return ast_cli_complete(a->word, options, a->n);
-		}
 		return NULL;
 	}
 
@@ -739,7 +734,7 @@ static char *handle_memory_atexit_summary(struct ast_cli_entry *e, int cmd, stru
 
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "memory atexit summary";
+		e->command = "memory atexit summary {off|byline|byfunc|byfile}";
 		e->usage =
 			"Usage: memory atexit summary {off|byline|byfunc|byfile}\n"
 			"       Summary of still allocated memory segments at exit options.\n"
@@ -751,11 +746,6 @@ static char *handle_memory_atexit_summary(struct ast_cli_entry *e, int cmd, stru
 			"       Note: byline, byfunc, and byfile are cumulative enables.\n";
 		return NULL;
 	case CLI_GENERATE:
-		if (a->pos == 3) {
-			const char * const options[] = { "off", "byline", "byfunc", "byfile", NULL };
-
-			return ast_cli_complete(a->word, options, a->n);
-		}
 		return NULL;
 	}
 
@@ -1054,7 +1044,7 @@ static char *handle_memory_backtrace(struct ast_cli_entry *e, int cmd, struct as
 {
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "memory backtrace";
+		e->command = "memory backtrace {on|off}";
 		e->usage =
 			"Usage: memory backtrace {on|off}\n"
 			"       Enable dumping an allocation backtrace with memory diagnostics.\n"
@@ -1062,11 +1052,6 @@ static char *handle_memory_backtrace(struct ast_cli_entry *e, int cmd, struct as
 			"       can be CPU intensive.\n";
 		return NULL;
 	case CLI_GENERATE:
-		if (a->pos == 2) {
-			const char * const options[] = { "off", "on", NULL };
-
-			return ast_cli_complete(a->word, options, a->n);
-		}
 		return NULL;
 	}
 
diff --git a/main/bridge.c b/main/bridge.c
index 6152b1b1743cadf26bf3aab875063d698cf2474c..7f6fbbef92755838774b74001747a872e3cdf1f8 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -5170,12 +5170,6 @@ static char *complete_bridge_participant(const char *bridge_name, const char *li
 		return NULL;
 	}
 
-	if (!state) {
-		ao2_ref(bridge, -1);
-		return ast_strdup("all");
-	}
-	state--;
-
 	{
 		SCOPED_LOCK(bridge_lock, bridge, ast_bridge_lock, ast_bridge_unlock);
 
@@ -5197,6 +5191,8 @@ static char *complete_bridge_participant(const char *bridge_name, const char *li
 
 static char *handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
+	static const char * const completions[] = { "all", NULL };
+	char *complete;
 	struct ast_bridge *bridge;
 
 	switch (cmd) {
@@ -5213,7 +5209,11 @@ static char *handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct
 			return complete_bridge_live(a->word, a->n);
 		}
 		if (a->pos == 3) {
-			return complete_bridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
+			complete = ast_cli_complete(a->word, completions, a->n);
+			if (!complete) {
+				complete = complete_bridge_participant(a->argv[2], a->line, a->word, a->pos, a->n - 1);
+			}
+			return complete;
 		}
 		return NULL;
 	}
diff --git a/main/ccss.c b/main/ccss.c
index f39eed9706af174945913a3728feee1bf449cf99..002b9a3dd25086563ae08c3494b1645a17d1f35d 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -4572,11 +4572,9 @@ static char *complete_core_id(const char *line, const char *word, int pos, int s
 
 static char *handle_cc_kill(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	static const char * const option[] = { "core", "all", NULL };
-
 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "cc cancel";
+		e->command = "cc cancel [core|all]";
 		e->usage =
 			"Usage: cc cancel can be used in two ways.\n"
 			"       1. 'cc cancel core [core ID]' will cancel the CC transaction with\n"
@@ -4584,10 +4582,7 @@ static char *handle_cc_kill(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 			"       2. 'cc cancel all' will cancel all active CC transactions.\n";
 		return NULL;
 	case CLI_GENERATE:
-		if (a->pos == 2) {
-			return ast_cli_complete(a->word, option, a->n);
-		}
-		if (a->pos == 3) {
+		if (a->pos == 3 && !strcasecmp(a->argv[2], "core")) {
 			return complete_core_id(a->line, a->word, a->pos, a->n);
 		}
 		return NULL;
diff --git a/main/cli.c b/main/cli.c
index 91350e988b3d9855c268b33f5b26ab6cf0905600..1af917776b6303b20081b6b9e02d4e1f11842bbf 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -917,6 +917,7 @@ static char *handle_modlist(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
 
 static char *handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
+	static const char * const completions[] = { "seconds", NULL };
 	struct timeval curtime = ast_tvnow();
 	int showuptime, printsec;
 
@@ -924,7 +925,7 @@ static char *handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_a
 	case CLI_INIT:
 		e->command = "core show calls [uptime]";
 		e->usage =
-			"Usage: core show calls [uptime] [seconds]\n"
+			"Usage: core show calls [uptime [seconds]]\n"
 			"       Lists number of currently active calls and total number of calls\n"
 			"       processed through PBX since last restart. If 'uptime' is specified\n"
 			"       the system uptime is also displayed. If 'seconds' is specified in\n"
@@ -934,7 +935,7 @@ static char *handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_a
 	case CLI_GENERATE:
 		if (a->pos != e->args)
 			return NULL;
-		return a->n == 0  ? ast_strdup("seconds") : NULL;
+		return ast_cli_complete(a->word, completions, a->n);
 	}
 
 	/* regular handler */
@@ -1104,7 +1105,9 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
 
 static char *handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	struct ast_channel *c=NULL;
+	struct ast_channel *c = NULL;
+	static const char * const completions[] = { "all", NULL };
+	char *complete;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -1117,7 +1120,14 @@ static char *handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_
 			"       will see the hangup request.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
+		if (a->pos != e->args) {
+			return NULL;
+		}
+		complete = ast_cli_complete(a->word, completions, a->n);
+		if (!complete) {
+			complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
+		}
+		return complete;
 	}
 
 	if (a->argc != 4) {
@@ -1429,6 +1439,8 @@ static int channel_set_debug(void *obj, void *arg, void *data, int flags)
 static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ast_channel *c = NULL;
+	static const char * const completions_all[] = { "all", NULL };
+	static const char * const completions_off[] = { "off", NULL };
 	struct channel_set_debug_args args = {
 		.fd = a->fd,
 	};
@@ -1441,10 +1453,15 @@ static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, str
 			"       Enables/disables debugging on all or on a specific channel.\n";
 		return NULL;
 	case CLI_GENERATE:
-		/* XXX remember to handle the optional "off" */
-		if (a->pos != e->args)
-			return NULL;
-		return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
+		if (a->pos == 4) {
+			char *complete = ast_cli_complete(a->word, completions_all, a->n);
+			if (!complete) {
+				complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
+			}
+			return complete;
+		} else if (a->pos == 5) {
+			return ast_cli_complete(a->word, completions_off, a->n);
+		}
 	}
 
 	if (cmd == (CLI_HANDLER + 1000)) {
diff --git a/main/pbx_app.c b/main/pbx_app.c
index bb60b8e78a0c649921169cce4049cad99615de28..1d90dac873d6b6e3d6e2e2f80278f8c7bb4cab61 100644
--- a/main/pbx_app.c
+++ b/main/pbx_app.c
@@ -315,7 +315,6 @@ static char *handle_show_applications(struct ast_cli_entry *e, int cmd, struct a
 	int like = 0, describing = 0;
 	int total_match = 0;    /* Number of matches in like clause */
 	int total_apps = 0;     /* Number of apps registered */
-	static const char * const choices[] = { "like", "describing", NULL };
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -327,7 +326,7 @@ static char *handle_show_applications(struct ast_cli_entry *e, int cmd, struct a
 			"       If 'describing', <text> will be a substring of the description\n";
 		return NULL;
 	case CLI_GENERATE:
-		return (a->pos != 3) ? NULL : ast_cli_complete(a->word, choices, a->n);
+		return NULL;
 	}
 
 	AST_RWLIST_RDLOCK(&apps);
diff --git a/main/pbx_hangup_handler.c b/main/pbx_hangup_handler.c
index 3b82547321e4c7af0ffd396622f71595a6554d71..376a98426dc7dc6099c284314346268c9d21781b 100644
--- a/main/pbx_hangup_handler.c
+++ b/main/pbx_hangup_handler.c
@@ -260,7 +260,7 @@ static char *handle_show_hangup_all(struct ast_cli_entry *e, int cmd, struct ast
 			"       Show hangup handlers for all channels.\n";
 		return NULL;
 	case CLI_GENERATE:
-		return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
+		return NULL;
 	}
 
 	if (a->argc < 4) {
diff --git a/res/res_sorcery_memory_cache.c b/res/res_sorcery_memory_cache.c
index 5f7ffb64ee87c03556f782d436663d5050d6173b..bf2347ccdecef00ef89d2e28db52fe09a7df0a82 100644
--- a/res/res_sorcery_memory_cache.c
+++ b/res/res_sorcery_memory_cache.c
@@ -1866,6 +1866,7 @@ static char *sorcery_memory_cache_expire(struct ast_cli_entry *e, int cmd, struc
 static char *sorcery_memory_cache_stale(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct sorcery_memory_cache *cache;
+	int reload = 0;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -1881,6 +1882,9 @@ static char *sorcery_memory_cache_stale(struct ast_cli_entry *e, int cmd, struct
 			return sorcery_memory_cache_complete_name(a->word, a->n);
 		} else if (a->pos == 5) {
 			return sorcery_memory_cache_complete_object_name(a->argv[4], a->word, a->n);
+		} else if (a->pos == 6) {
+			static const char * const completions[] = { "reload", NULL };
+			return ast_cli_complete(a->word, completions, a->n);
 		} else {
 			return NULL;
 		}
@@ -1890,6 +1894,14 @@ static char *sorcery_memory_cache_stale(struct ast_cli_entry *e, int cmd, struct
 		return CLI_SHOWUSAGE;
 	}
 
+	if (a->argc == 7) {
+		if (!strcasecmp(a->argv[6], "reload")) {
+			reload = 1;
+		} else {
+			return CLI_SHOWUSAGE;
+		}
+	}
+
 	cache = ao2_find(caches, a->argv[4], OBJ_SEARCH_KEY);
 	if (!cache) {
 		ast_cli(a->fd, "Specified sorcery memory cache '%s' does not exist\n", a->argv[4]);
@@ -1910,7 +1922,7 @@ static char *sorcery_memory_cache_stale(struct ast_cli_entry *e, int cmd, struct
 		if (!mark_object_as_stale_in_cache(cache, a->argv[5])) {
 			ast_cli(a->fd, "Successfully marked object '%s' in memory cache '%s' as stale\n",
 				a->argv[5], a->argv[4]);
-			if (a->argc == 7 && ast_true(a->argv[6])) {
+			if (reload) {
 				struct sorcery_memory_cached_object *cached;
 
 				cached = ao2_find(cache->objects, a->argv[5], OBJ_SEARCH_KEY | OBJ_NOLOCK);