RZ_API RZ_OWN RzList /*<RzBinImport *>*/ *rz_bin_dex_imports(RZ_NONNULL RzBinDex *dex) {
	rz_return_val_if_fail(dex, NULL);

	DexFieldId *field_id;
	DexMethodId *method_id;
	DexClassDef *class_def;
	RzList *imports = NULL;
	ut32 *class_ids = NULL;
	void **vit;

	ut32 n_classes = rz_pvector_len(dex->class_defs);
	if (n_classes < 1) {
		return rz_list_newf((RzListFree)rz_bin_import_free);
	}

	class_ids = RZ_NEWS0(ut32, n_classes);
	if (!class_ids) {
		return NULL;
	}

	ut32 j = 0;
	rz_pvector_foreach (dex->class_defs, vit) {
		class_def = (DexClassDef *)*vit;
		class_ids[j] = class_def->class_idx;
		j++;
	}

	imports = rz_list_newf((RzListFree)rz_bin_import_free);
	if (!imports) {
		free(class_ids);
		return NULL;
	}

	ut32 ordinal = 0;
	rz_pvector_foreach (dex->field_ids, vit) {
		field_id = (DexFieldId *)*vit;
		bool class_found = false;
		for (ut32 i = 0; i < n_classes; ++i) {
			if (field_id->class_idx == class_ids[i]) {
				class_found = true;
				break;
			}
		}
		if (class_found) {
			continue;
		}

		RzBinImport *import = RZ_NEW0(RzBinImport);
		if (!import) {
			break;
		}

		char *object = dex_resolve_type_id(dex, field_id->class_idx);
		if (RZ_STR_ISEMPTY(object)) {
			free(object);
			free(import);
			break;
		}
		rz_str_replace_char(object, ';', 0);

		char *class_name = (char *)rz_str_rchr(object, NULL, '/');
		if (class_name) {
			class_name[0] = 0;
			class_name++;
		}
		rz_str_replace_ch(object, '/', '.', 1);

		import->name = dex_resolve_string_id(dex, field_id->name_idx);
		import->libname = class_name ? strdup(object + 1) : NULL;
		import->classname = strdup(class_name ? class_name : object + 1);
		import->bind = RZ_BIN_BIND_WEAK_STR;
		import->type = RZ_BIN_TYPE_FIELD_STR;
		import->ordinal = ordinal;
		free(object);

		if (!rz_list_append(imports, import)) {
			rz_bin_import_free(import);
			break;
		}
		ordinal++;
	}

	rz_pvector_foreach (dex->method_ids, vit) {
		method_id = (DexMethodId *)*vit;
		bool class_found = false;
		for (ut32 i = 0; i < n_classes; ++i) {
			if (method_id->class_idx == class_ids[i]) {
				class_found = true;
				break;
			}
		}
		if (class_found) {
			continue;
		}

		RzBinImport *import = RZ_NEW0(RzBinImport);
		if (!import) {
			break;
		}

		char *object = dex_resolve_type_id(dex, method_id->class_idx);
		if (RZ_STR_ISEMPTY(object)) {
			free(object);
			rz_bin_import_free(import);
			break;
		}
		rz_str_replace_char(object, ';', 0);

		char *class_name = (char *)rz_str_rchr(object, NULL, '/');
		if (class_name) {
			class_name[0] = 0;
			class_name++;
		}
		rz_str_replace_ch(object, '/', '.', 1);

		char *name = dex_resolve_string_id(dex, method_id->name_idx);
		import->name = dex_resolve_proto_id(dex, name, method_id->proto_idx, false);
		import->libname = class_name ? strdup(object + 1) : NULL;
		import->classname = strdup(class_name ? class_name : object + 1);
		import->bind = RZ_BIN_BIND_WEAK_STR;
		import->type = RZ_BIN_TYPE_FUNC_STR;
		import->ordinal = ordinal;
		free(name);
		free(object);

		if (!rz_list_append(imports, import)) {
			rz_bin_import_free(import);
			break;
		}
		ordinal++;
	}

	free(class_ids);
	return imports;
}
RZ_API RZ_OWN RzList   *rz_bin_dex_imports(RZ_NONNULL RzBinDex *dex) {
	rz_return_val_if_fail(dex, NULL);

	DexFieldId *field_id;
	DexMethodId *method_id;
	DexClassDef *class_def;
	RzList *imports = NULL;
	ut32 *class_ids = NULL;
	void **vit;

	ut32 n_classes = rz_pvector_len(dex->class_defs);
	if (n_classes < 1) {
		return rz_list_newf((RzListFree)rz_bin_import_free);
	}

	class_ids = RZ_NEWS0(ut32, n_classes);
	if (!class_ids) {
		return NULL;
	}

	ut32 j = 0;
	rz_pvector_foreach (dex->class_defs, vit) {
		class_def = (DexClassDef *)*vit;
		class_ids[j] = class_def->class_idx;
		j++;
	}

	imports = rz_list_newf((RzListFree)rz_bin_import_free);
	if (!imports) {
		free(class_ids);
		return NULL;
	}

	ut32 ordinal = 0;
	rz_pvector_foreach (dex->field_ids, vit) {
		field_id = (DexFieldId *)*vit;
		bool class_found = false;
		for (ut32 i = 0; i < n_classes; ++i) {
			if (field_id->class_idx == class_ids[i]) {
				class_found = true;
				break;
			}
		}
		if (class_found) {
			continue;
		}

		RzBinImport *import = RZ_NEW0(RzBinImport);
		if (!import) {
			break;
		}

		char *object = dex_resolve_type_id(dex, field_id->class_idx);
		if (RZ_STR_ISEMPTY(object)) {
			free(object);
			free(import);
			break;
		}
		rz_str_replace_char(object, ';', 0);

		char *class_name = (char *)rz_str_rchr(object, NULL, '/');
		if (class_name) {
			class_name[0] = 0;
			class_name++;
		}
		rz_str_replace_ch(object, '/', '.', 1);

		import->name = dex_resolve_string_id(dex, field_id->name_idx);
		import->libname = class_name ? strdup(object + 1) : NULL;
		import->classname = strdup(class_name ? class_name : object + 1);
		import->bind = RZ_BIN_BIND_WEAK_STR;
		import->type = RZ_BIN_TYPE_FIELD_STR;
		import->ordinal = ordinal;
		free(object);

		if (!rz_list_append(imports, import)) {
			rz_bin_import_free(import);
			break;
		}
		ordinal++;
	}

	rz_pvector_foreach (dex->method_ids, vit) {
		method_id = (DexMethodId *)*vit;
		bool class_found = false;
		for (ut32 i = 0; i < n_classes; ++i) {
			if (method_id->class_idx == class_ids[i]) {
				class_found = true;
				break;
			}
		}
		if (class_found) {
			continue;
		}

		RzBinImport *import = RZ_NEW0(RzBinImport);
		if (!import) {
			break;
		}

		char *object = dex_resolve_type_id(dex, method_id->class_idx);
		if (RZ_STR_ISEMPTY(object)) {
			free(object);
			rz_bin_import_free(import);
			break;
		}
		rz_str_replace_char(object, ';', 0);

		char *class_name = (char *)rz_str_rchr(object, NULL, '/');
		if (class_name) {
			class_name[0] = 0;
			class_name++;
		}
		rz_str_replace_ch(object, '/', '.', 1);

		char *name = dex_resolve_string_id(dex, method_id->name_idx);
		import->name = dex_resolve_proto_id(dex, name, method_id->proto_idx, false);
		import->libname = class_name ? strdup(object + 1) : NULL;
		import->classname = strdup(class_name ? class_name : object + 1);
		import->bind = RZ_BIN_BIND_WEAK_STR;
		import->type = RZ_BIN_TYPE_FUNC_STR;
		import->ordinal = ordinal;
		free(name);
		free(object);

		if (!rz_list_append(imports, import)) {
			rz_bin_import_free(import);
			break;
		}
		ordinal++;
	}

	free(class_ids);
	return imports;
}