void daemon_close(struct razer_daemon *daemon)
{
	#ifdef USE_DBUS
		daemon_dbus_close(daemon);
	#endif
	list_Close(daemon->libs);
	list_Close(daemon->fx_render_nodes);
	list_Close(daemon->render_nodes);
	list_Close(daemon->effects);
 	razer_close(daemon->chroma);
 	free(daemon);
}
void daemon_free_parameters(list *parameters)
{
	while(!list_IsEmpty(parameters))
	{
			daemon_free_parameter((struct razer_parameter*)list_Pop(parameters));
	}
	list_Close(parameters);
}
void str_FreeTokens(list *tokens)
{
  list_IterationReset(tokens);
  while(list_IterationUnfinished(tokens))
  {
    char *token = list_Iterate(tokens);
    free(token);
  }
  list_Close(tokens);
}
void daemon_compute_render_nodes(struct razer_daemon *daemon)
{
	//struct razer_queue *queue = daemon_create_queue();
	list *queue = list_Create(0,0);
	list_Clear(daemon->render_nodes);
	struct razer_fx_render_node *rn = daemon_get_render_node(daemon,daemon->frame_buffer_linked_uid);
	if(rn)
	{
		list_Queue(queue,rn);
		daemon_compute_append_queue(daemon,queue);
	}
	//daemon_free_queue(&queue);
	list_Close(queue);
	daemon->is_render_nodes_dirty = 0;
}
struct razer_daemon *daemon_open(void)
{
 	//signal(SIGINT,stop);
 	//signal(SIGKILL,stop);
        //signal(SIGTERM,stop);
	struct razer_daemon *daemon = (struct razer_daemon*)malloc(sizeof(struct razer_daemon));
 	daemon->chroma = NULL;
 	daemon->running = 1;
 	daemon->is_paused = 0;
 	daemon->fps = 12;
 	daemon->libs_uid = 1;
 	daemon->libs = list_Create(0,0);
 	daemon->effects_uid = 1;
 	daemon->effects = list_Create(0,0);
 	daemon->fx_render_nodes_uid = 1;
 	daemon->fx_render_nodes = list_Create(0,0);//list of all render_nodes available
 	daemon->is_render_nodes_dirty = 0;
 	daemon->render_nodes = list_Create(0,0);

 	if(!(daemon->chroma=razer_open()))
 	{
 		free(daemon->chroma);
		list_Close(daemon->libs);
		list_Close(daemon->fx_render_nodes);
		list_Close(daemon->render_nodes);
		list_Close(daemon->effects);
 		free(daemon);
		return(NULL);
	}
	#ifdef USE_DBUS
	 	daemon->dbus = NULL;
		#ifdef USE_DEBUGGING
			printf("dbus: opened\n");
		#endif
	 	if(!daemon_dbus_open(daemon))
	 	{
	 		free(daemon->chroma);
			list_Close(daemon->libs);
			list_Close(daemon->fx_render_nodes);
			list_Close(daemon->render_nodes);
			list_Close(daemon->effects);
	 		free(daemon);
			return(NULL);
		}
	 	if(!daemon_dbus_announce(daemon))
	 	{
 			free(daemon->chroma);
			list_Close(daemon->libs);
			list_Close(daemon->fx_render_nodes);
			list_Close(daemon->render_nodes);
			list_Close(daemon->effects);
	 		free(daemon);
			return(NULL);
		}
	#endif
	razer_set_input_handler(daemon->chroma,daemon_input_event_handler);
	daemon->chroma->tag = daemon;
	daemon->frame_buffer = razer_create_rgb_frame();
	daemon->frame_buffer_linked_uid = 0;
	daemon->return_render_node = NULL; //TODO remember what i wanted to achieve with this variable ... :-)

	razer_set_custom_mode(daemon->chroma);
	razer_clear_all(daemon->chroma->keys);
	razer_update_keys(daemon->chroma,daemon->chroma->keys);

	//TODO Move to configuration options (dbus race condition present)

	#ifdef USE_DEBUGGING
		struct daemon_lib *lib = daemon_load_fx_lib(daemon,"daemon/fx/pez2001_collection_debug.so");
	#else
		//void *lib = daemon_load_fx_lib(daemon,"daemon/fx/pez2001_collection.so");
		struct daemon_lib *lib = daemon_load_fx_lib(daemon,"/usr/share/razer_bcd/fx/pez2001_collection.so");
	#endif
	if(lib)
		daemon_register_lib(daemon,lib);

	#ifdef USE_DEBUGGING
		struct daemon_lib *blib = daemon_load_fx_lib(daemon,"daemon/fx/pez2001_light_blast_debug.so");
	#else
		struct daemon_lib *blib = daemon_load_fx_lib(daemon,"/usr/share/razer_bcd/fx/pez2001_light_blast.so");
	#endif
	if(lib)
		daemon_register_lib(daemon,blib);

	//daemon->render_node = daemon_create_render_node(daemon,daemon_get_effect(daemon,2),-1,-1,0,"First Render Node","Default Render Node");
	daemon->render_node = daemon_create_render_node(daemon,daemon_get_effect(daemon,11),-1,-1,0,"First Render Node","Default Render Node");
	daemon_register_render_node(daemon,daemon->render_node);
	daemon_compute_render_nodes(daemon);
	daemon_connect_frame_buffer(daemon,daemon->render_node);

	/*daemon->render_node = daemon_create_render_node(daemon,daemon_get_effect(daemon,3),-1,-1,0,"Second Test Render Node","Additional Testing Render Node");
	daemon_register_render_node(daemon,daemon->render_node);
	daemon_compute_render_nodes(daemon);
	*/
	
	// Catch SIGTERM
	struct sigaction sigterm_action;
	memset(&sigterm_action, 0, sizeof(struct sigaction));
	sigterm_action.sa_handler = got_sigterm_signal;
	sigaction(SIGTERM, &sigterm_action, NULL);
	
 	return(daemon);
}