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

	DexMethodId *method_id;
	DexClassDef *class_def;
	RzList *libraries = 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)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++;
	}

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

	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;
		}

		char *object = dex_resolve_type_id(dex, method_id->class_idx);
		if (RZ_STR_ISEMPTY(object) || *object != 'L' || !strncmp(object, "Ljava/", strlen("Ljava/"))) {
			free(object);
			continue;
		}

		char *p = object;
		if ((p = strchr(p, '/')) && (p = strchr(p + 1, '/'))) {
			*p = 0;
			p = rz_str_newf("%s/*;", object);
			free(object);
			object = p;
		}

		if (rz_list_find(libraries, object, compare_strings)) {
			free(object);
			continue;
		}

		if (!rz_list_append(libraries, object)) {
			free(object);
			break;
		}
	}

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

	DexMethodId *method_id;
	DexClassDef *class_def;
	RzList *libraries = 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)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++;
	}

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

	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;
		}

		char *object = dex_resolve_type_id(dex, method_id->class_idx);
		if (RZ_STR_ISEMPTY(object) || *object != 'L' || !strncmp(object, "Ljava/", strlen("Ljava/"))) {
			free(object);
			continue;
		}

		char *p = object;
		if ((p = strchr(p, '/')) && (p = strchr(p + 1, '/'))) {
			*p = 0;
			p = rz_str_newf("%s/*;", object);
			free(object);
			object = p;
		}

		if (rz_list_find(libraries, object, compare_strings)) {
			free(object);
			continue;
		}

		if (!rz_list_append(libraries, object)) {
			free(object);
			break;
		}
	}

	free(class_ids);
	return libraries;
}