osync_bool osync_plugin_env_load_module(OSyncPluginEnv *env, const char *filename, OSyncError **error)
{
	OSyncModule *module = NULL;
	
	osync_trace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, env, filename, error);
	osync_assert(env);
	osync_assert(filename);
	
	module = osync_module_new(error);
	if (!module)
		goto error;
	
	if (!osync_module_load(module, filename, error)) {
		osync_trace(TRACE_INTERNAL, "Unable to load module %s: %s", filename, osync_error_print(error));
		osync_module_free(module);
	} else {
		if (!osync_module_check(module, error)) {
			if (osync_error_is_set(error)) {
				osync_trace(TRACE_INTERNAL, "Module check error for %s: %s", filename, osync_error_print(error));
			}
			osync_module_unload(module);
			osync_module_free(module);
			osync_trace(TRACE_EXIT, "%s: Unable to load module", __func__);
			return FALSE;
		}
		
		if (!osync_module_get_sync_info(module, env, error)) {
			if (osync_error_is_set(error))
				goto error_free_module;
			
			osync_module_unload(module);
			osync_module_free(module);
			osync_trace(TRACE_EXIT, "%s: No get_sync_info function", __func__);
			return FALSE;
		}
		env->modules = g_list_append(env->modules, module);
	}
	
	osync_trace(TRACE_EXIT, "%s", __func__);
	return TRUE;

error_free_module:
	osync_module_unload(module);
	osync_module_free(module);
error:
	osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
	return FALSE;
}
END_TEST

START_TEST (module_function_false)
{
	char *testbed = setup_testbed(NULL);
	
	OSyncError *error = NULL;
	OSyncModule *module = osync_module_new(&error);
	fail_unless(module != NULL, NULL);
	fail_unless(error == NULL, NULL);
	
	char *curdir = g_get_current_dir();
	char *path = g_strdup_printf("%s/formats/mock-format.%s", curdir, G_MODULE_SUFFIX);
	fail_unless(osync_module_load(module, path, &error), NULL);
	fail_unless(error == NULL, NULL);
	g_free(path);
	g_free(curdir);
	
	void *func = osync_module_get_function(module, "get_version1", &error);
	fail_unless(func == NULL, NULL);
	fail_unless(error != NULL, NULL);
	osync_error_unref(&error);
	
	osync_module_unload(module);
	
	osync_module_unref(module);
	
	destroy_testbed(testbed);
}
/*! @brief Used to free a module
 * 
 * Frees a module
 * 
 * @param module Pointer to the module
 * 
 */
void osync_module_free(OSyncModule *module)
{
  osync_trace(TRACE_ENTRY, "%s(%p)", __func__, module);
  if (module->module)
    osync_module_unload(module);
		
  if (module->path)
    g_free(module->path);
	
  g_free(module);
	
  osync_trace(TRACE_EXIT, "%s", __func__);
}
void osync_module_unref(OSyncModule *module)
{
	osync_trace(TRACE_ENTRY, "%s(%p)", __func__, module);
	osync_assert(module);
	if (g_atomic_int_dec_and_test(&(module->ref_count))) {
		if (module->module)
			osync_module_unload(module);
		
		if (module->path)
			osync_free(module->path);
	
		osync_free(module);
	}
	osync_trace(TRACE_EXIT, "%s", __func__);
}
void osync_plugin_env_free(OSyncPluginEnv *env)
{
	osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env);
	osync_assert(env);
	
	/* Free the plugins */
	while (env->plugins) {
		osync_plugin_unref(env->plugins->data);
		env->plugins = g_list_remove(env->plugins, env->plugins->data);
	}
	
	/* Unload all modules */
	while (env->modules) {
		osync_module_unload(env->modules->data);
		osync_module_free(env->modules->data);
		env->modules = g_list_remove(env->modules, env->modules->data);
	}
	
	g_free(env);
	
	osync_trace(TRACE_EXIT, "%s", __func__);
}