static int cmd_anal_all(RCore *core, const char *input) {
	switch (*input) {
	case '?': r_core_cmd_help (core, help_msg_aa); break;
	case 'b': // "aab"
		cmd_anal_blocks (core, input + 1);
		break; // "aab"
	case 'f': // "aaf"
		{
			int analHasnext = r_config_get_i (core->config, "anal.hasnext");
			r_config_set_i (core->config, "anal.hasnext", true);
			r_core_cmd0 (core, "afr@@c:isq");
			r_config_set_i (core->config, "anal.hasnext", analHasnext);
		}
		break;
	case 'c': // "aac"
		switch (input[1]) {
		case '*':
			cmd_anal_calls (core, input + 1, true); break; // "aac*"
		default:
			cmd_anal_calls (core, input + 1, false); break; // "aac"
		}
	case 'j': cmd_anal_jumps (core, input + 1); break; // "aaj"
	case '*': // "aa*"
		r_core_cmd0 (core, "af @@ sym.*");
		r_core_cmd0 (core, "af @@ entry*");
		break;
	case 'd': // "aad"
		cmd_anal_aad (core, input);
		break;
	case 'v': // "aav"
		cmd_anal_aav (core, input);
		break;
	case 'u': // "aau" - print areas not covered by functions
		r_core_anal_nofunclist (core, input + 1);
		break;
	case 'i': // "aai"
		r_core_anal_info (core, input + 1);
		break;
	case 's': // "aas"
		r_core_cmd0 (core, "af @@= `isq~[0]`");
		r_core_cmd0 (core, "af @@ entry*");
		break;
	case 'n': // "aan"
		r_core_anal_autoname_all_fcns (core);
		break; //aan
	case 'p': // "aap"
		if (*input == '?') {
			// TODO: accept parameters for ranges
			eprintf ("Usage: /aap   ; find in memory for function preludes");
		} else {
			r_core_search_preludes (core);
		}
		break;
	case '\0': // "aa"
	case 'a':
		if (input[0] && (input[1] == '?' || (input[1] && input[2] == '?'))) {
			r_cons_println ("Usage: See aa? for more help");
		} else {
			char *dh_orig = NULL;
			if (!strncmp (input, "aaaaa", 5)) {
				eprintf ("An r2 developer is coming to your place to manually analyze this program. Please wait for it\n");
				if (r_config_get_i (core->config, "scr.interactive")) {
					r_cons_any_key (NULL);
				}
				goto jacuzzi;
			}
			ut64 curseek = core->offset;
			rowlog (core, "Analyze all flags starting with sym. and entry0 (aa)");
			r_cons_break_push (NULL, NULL);
			r_cons_break_timeout (r_config_get_i (core->config, "anal.timeout"));
			r_core_anal_all (core);
			rowlog_done (core);
			dh_orig = core->dbg->h
					? strdup (core->dbg->h->name)
					: strdup ("esil");
			if (core->io && core->io->desc && core->io->desc->plugin && !core->io->desc->plugin->isdbg) {
				//use dh_origin if we are debugging
				R_FREE (dh_orig);
			}
			if (r_cons_is_breaked ()) {
				goto jacuzzi;
			}
			r_cons_clear_line (1);
			if (*input == 'a') { // "aaa"
				if (dh_orig && strcmp (dh_orig, "esil")) {
					r_core_cmd0 (core, "dL esil");
				}
				int c = r_config_get_i (core->config, "anal.calls");
				if (should_aav (core)) {
					rowlog (core, "\nAnalyze value pointers (aav)");
					r_core_cmd0 (core, "aav");
					if (r_cons_is_breaked ()) {
						goto jacuzzi;
					}
				}
				r_config_set_i (core->config, "anal.calls", 1);
				r_core_cmd0 (core, "s $S");
				rowlog (core, "Analyze len bytes of instructions for references (aar)");
				if (r_cons_is_breaked ()) {
					goto jacuzzi;
				}
				(void)r_core_anal_refs (core, ""); // "aar"
				rowlog_done (core);
				if (r_cons_is_breaked ()) {
					goto jacuzzi;
				}
				rowlog (core, "Analyze function calls (aac)");
				(void) cmd_anal_calls (core, "", false); // "aac"
				r_core_seek (core, curseek, 1);
				// rowlog (core, "Analyze data refs as code (LEA)");
				// (void) cmd_anal_aad (core, NULL); // "aad"
				rowlog_done (core);
				if (r_cons_is_breaked ()) {
					goto jacuzzi;
				}
				if (input[1] == 'a') { // "aaaa"
					bool ioCache = r_config_get_i (core->config, "io.pcache");
					r_config_set_i (core->config, "io.pcache", 1);
					rowlog (core, "Emulate code to find computed references (aae)");
					r_core_cmd0 (core, "aae $SS @ $S");
					rowlog_done (core);
					rowlog (core, "Analyze consecutive function (aat)");
					r_core_cmd0 (core, "aat");
					rowlog_done (core);
					// drop cache writes is no cache was
					if (!ioCache) {
						r_core_cmd0 (core, "wc-*");
					}
					r_config_set_i (core->config, "io.pcache", ioCache);
				} else {
					rowlog (core, "Use -AA or aaaa to perform additional experimental analysis.");
					rowlog_done (core);
				}
				r_config_set_i (core->config, "anal.calls", c);
				rowlog (core, "Constructing a function name for fcn.* and sym.func.* functions (aan)");
				if (r_cons_is_breaked ()) {
					goto jacuzzi;
				}
				if (r_config_get_i (core->config, "anal.autoname")) {
					r_core_anal_autoname_all_fcns (core);
					rowlog_done (core);
				}
				if (input[1] == 'a') { // "aaaa"
					bool ioCache = r_config_get_i (core->config, "io.pcache");
					r_config_set_i (core->config, "io.pcache", 1);
					if (sdb_count (core->anal->sdb_zigns) > 0) {
						rowlog (core, "Check for zignature from zigns folder (z/)");
						r_core_cmd0 (core, "z/");
					}
					rowlog (core, "Type matching analysis for all functions (afta)");
					r_core_cmd0 (core, "afta");
					rowlog_done (core);
					if (!ioCache) {
						r_core_cmd0 (core, "wc-*");
					}
					r_config_set_i (core->config, "io.pcache", ioCache);
				}
				r_core_cmd0 (core, "s-");
				if (dh_orig) {
					r_core_cmdf (core, "dL %s;dpa", dh_orig);
				}
			}
			r_core_seek (core, curseek, 1);
		jacuzzi:
			flag_every_function (core);
			r_cons_break_pop ();
			R_FREE (dh_orig);
		}
		break;
	case 't': { // "aat"
		ut64 cur = core->offset;
		bool hasnext = r_config_get_i (core->config, "anal.hasnext");
		RListIter *iter;
		RIOMap* map;
		RList *list = r_core_get_boundaries_prot (core, R_IO_EXEC, NULL, "anal");
		r_list_foreach (list, iter, map) {
			r_core_seek (core, map->itv.addr, 1);
			r_config_set_i (core->config, "anal.hasnext", 1);
			r_core_cmd0 (core, "afr");
			r_config_set_i (core->config, "anal.hasnext", hasnext);
		}
		r_core_seek (core, cur, 1);
		break;
	}
	case 'T': // "aaT"
		cmd_anal_aftertraps (core, input + 1);
		break;
	case 'E': // "aaE"
		r_core_cmd0 (core, "aef @@f");
		break;
	case 'e': // "aae"
		if (input[1]) {
			const char *len = (char *) input + 1;
			char *addr = strchr (input + 2, ' ');
			if (addr) {
				*addr++ = 0;
			}
			r_core_anal_esil (core, len, addr);
		} else {
			ut64 at = core->offset;
			RIOMap* map;
			RListIter *iter;
			RList *list = r_core_get_boundaries_prot (core, -1, NULL, "anal");
			r_list_foreach (list, iter, map) {
				r_core_seek (core, map->itv.addr, 1);
				r_core_anal_esil (core, "$SS", NULL);
			}
			r_core_seek (core, at, 1);
		}
		break;
	case 'r':
		(void)r_core_anal_refs (core, input + 1);
		break;
	default:
		r_core_cmd_help (core, help_msg_aa);
		break;
	}

	return true;
}