RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2) {
	RzListIter *iter;
	ut64 min = 0;
	ut64 max = 0;
	int first = 1;
	RzAnalysisBlock *bb;
	RzAnalysisFunction *f1 = rz_analysis_get_function_at(core->analysis, addr);
	RzAnalysisFunction *f2 = rz_analysis_get_function_at(core->analysis, addr2);
	if (!f1 || !f2) {
		eprintf("Cannot find function\n");
		return;
	}
	if (f1 == f2) {
		eprintf("Cannot merge the same function\n");
		return;
	}
	// join all basic blocks from f1 into f2 if they are not
	// delete f2
	eprintf("Merge 0x%08" PFMT64x " into 0x%08" PFMT64x "\n", addr, addr2);
	rz_list_foreach (f1->bbs, iter, bb) {
		if (first) {
			min = bb->addr;
			max = bb->addr + bb->size;
			first = 0;
		} else {
			if (bb->addr < min) {
				min = bb->addr;
			}
			if (bb->addr + bb->size > max) {
				max = bb->addr + bb->size;
			}
		}
	}
	rz_list_foreach (f2->bbs, iter, bb) {
		if (first) {
			min = bb->addr;
			max = bb->addr + bb->size;
			first = 0;
		} else {
			if (bb->addr < min) {
				min = bb->addr;
			}
			if (bb->addr + bb->size > max) {
				max = bb->addr + bb->size;
			}
		}
		rz_analysis_function_add_block(f1, bb);
	}
	// TODO: import data/code/refs
	rz_analysis_function_delete(f2);
	// update size
	rz_analysis_function_relocate(f2, RZ_MIN(addr, addr2));
}
RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2) {
	RzListIter *iter;
	ut64 min = 0;
	ut64 max = 0;
	int first = 1;
	RzAnalysisBlock *bb;
	RzAnalysisFunction *f1 = rz_analysis_get_function_at(core->analysis, addr);
	RzAnalysisFunction *f2 = rz_analysis_get_function_at(core->analysis, addr2);
	if (!f1 || !f2) {
		eprintf("Cannot find function\n");
		return;
	}
	if (f1 == f2) {
		eprintf("Cannot merge the same function\n");
		return;
	}
	 
	 
	eprintf("Merge 0x%08" PFMT64x " into 0x%08" PFMT64x "\n", addr, addr2);
	rz_list_foreach (f1->bbs, iter, bb) {
		if (first) {
			min = bb->addr;
			max = bb->addr + bb->size;
			first = 0;
		} else {
			if (bb->addr < min) {
				min = bb->addr;
			}
			if (bb->addr + bb->size > max) {
				max = bb->addr + bb->size;
			}
		}
	}
	rz_list_foreach (f2->bbs, iter, bb) {
		if (first) {
			min = bb->addr;
			max = bb->addr + bb->size;
			first = 0;
		} else {
			if (bb->addr < min) {
				min = bb->addr;
			}
			if (bb->addr + bb->size > max) {
				max = bb->addr + bb->size;
			}
		}
		rz_analysis_function_add_block(f1, bb);
	}
	 
	rz_analysis_function_delete(f2);
	 
	rz_analysis_function_relocate(f2, RZ_MIN(addr, addr2));
}