<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>event.c</filename>
    </added>
    <added>
      <filename>track.c</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -6,7 +6,7 @@ G_LIBS = -lglib-2.0
 INCLUDES = -I$(includedir)/glib-2.0 -I$(exec_prefix)/lib/glib-2.0/include 
 LDADD = $(G_LIBS)
 
-AM_LDFLAGS = `pkg-config --libs libcurl`
+AM_LDFLAGS = `pkg-config --libs libcurl` `pkg-config --libs gthread-2.0`
 AM_CFLAGS = -std=c99 -Wall
 
 include_HEADERS = callback.h album.h artist.h lastfm.h
@@ -17,7 +17,7 @@ lastfm_LDFLAGS = -llastfm
 
 lib_LTLIBRARIES = liblastfm.la
 
-liblastfm_la_SOURCES = include.c communication.c authentication.c tag.c album.c artist.c liblastfm.c
+liblastfm_la_SOURCES = include.c communication.c authentication.c tag.c album.c artist.c lfmobjects.c liblastfm.c
 liblastfm_la_CFLAGS = -I'pkg-config --cflags libcurl' $(AM_CFLAGS)
 
 liblastfm_la_LDFLAGS = -version-info 0:0:0</diff>
      <filename>Makefile.am</filename>
    </modified>
    <modified>
      <diff>@@ -74,7 +74,7 @@ void album_get_info(const gchar* artist, const gchar* album, const lfmget* call,
 	para-&gt;value = album;
 	addv(lfmparametervalue, parameters, para);
 	
-	get_data_from_method(call-&gt;method, parameters, callback, user_data);
+	get_data_from_method(call, parameters, callback, user_data);
 	
 	destroyv(lfmparametervalue, parameters);
 }
@@ -124,12 +124,12 @@ void album_get_image_url(const gchar* artist, const gchar* album, const enum ima
 	album_get_info(artist, album, call, callback, user_data);
 }
 
-void album_get_listener_count(const gchar* artist, const gchar* album, guint_callback callback, gpointer user_data)
+void album_get_listener_count(const gchar* artist, const gchar* album, uint_callback callback, gpointer user_data)
 {
 	album_get_info(artist, album, &amp;primary_methods[ALBUM_LISTENER_COUNT], callback, user_data);	
 }
 
-void album_get_play_count(const gchar* artist, const gchar* album, guint_callback callback, gpointer user_data)
+void album_get_play_count(const gchar* artist, const gchar* album, uint_callback callback, gpointer user_data)
 {
 	album_get_info(artist, album, &amp;primary_methods[ALBUM_PLAY_COUNT], callback, user_data);	
 }</diff>
      <filename>album.c</filename>
    </modified>
    <modified>
      <diff>@@ -5,13 +5,13 @@
 static const lfmmethod artist_method_declarations[] =
 {
 	{&quot;artist.addTags&quot;, {{&quot;tags&quot;, utf8_array2csl, FALSE}}},
-    {&quot;artist.getEvents&quot;, {}},
+    {&quot;artist.getEvents&quot;},
     {&quot;artist.getInfo&quot;, {{&quot;mbid&quot;, NULL, TRUE}}},
     {&quot;artist.getSimilar&quot;, {{&quot;limit&quot;, guint2utf8, TRUE}}},
-    {&quot;artist.getTopAlbums&quot;, {}},
-    {&quot;artist.getTopFans&quot;, {}},
-    {&quot;artist.getTopTags&quot;,  {}},
-    {&quot;artist.getTopTracks&quot;, {}},
+    {&quot;artist.getTopAlbums&quot;},
+    {&quot;artist.getTopFans&quot;},
+    {&quot;artist.getTopTags&quot;},
+    {&quot;artist.getTopTracks&quot;},
     {&quot;artist.removeTag&quot;, {{&quot;tag&quot;, NULL, FALSE}}},
     {&quot;artist.search&quot;, {{&quot;limit&quot;, guint2utf8, TRUE}, {&quot;page&quot;, guint2utf8, TRUE}}},
     {&quot;artist.share&quot;, {{&quot;recipient&quot;, utf8_array2csl, FALSE}, {&quot;message&quot;, NULL, TRUE}}},
@@ -105,7 +105,7 @@ G_GNUC_NULL_TERMINATED void artist_get_info_with_parameters(const gchar* artist,
 	
 	fill_parameters(parameters, call-&gt;method, vl);
 	
-	get_data_from_method(call-&gt;method, parameters, callback, user_data);
+	get_data_from_method(call, parameters, callback, user_data);
 	
 	va_end(vl);
 	destroyv(lfmparametervalue, parameters);
@@ -158,12 +158,12 @@ void artist_is_streamable(const gchar* artist, boolean_callback callback, gpoint
 	artist_get_info(artist, &amp;primary_methods[ARTIST_STREAMABLE], callback, user_data);
 }
 
-void artist_get_listener_count(const gchar* artist, guint_callback callback, gpointer user_data)
+void artist_get_listener_count(const gchar* artist, uint_callback callback, gpointer user_data)
 {
 	artist_get_info(artist, &amp;primary_methods[ARTIST_LISTENER_COUNT], callback, user_data);
 }
 
-void artist_get_play_count(const gchar* artist, guint_callback callback, gpointer user_data)
+void artist_get_play_count(const gchar* artist, uint_callback callback, gpointer user_data)
 {
 	artist_get_info(artist, &amp;primary_methods[ARTIST_PLAY_COUNT], callback, user_data);
 }</diff>
      <filename>artist.c</filename>
    </modified>
    <modified>
      <diff>@@ -19,8 +19,8 @@ void artist_get_musicbrainz_id(const gchar* artist, utf8_callback callback, gpoi
 void artist_get_url(const gchar* artist, url_callback callback, gpointer user_data);
 void artist_get_image_url(const gchar* artist, image_size size, url_callback callback, gpointer user_data);
 void artist_is_streamable(const gchar* artist, boolean_callback callback, gpointer user_data);
-void artist_get_listener_count(const gchar* artist, guint_callback callback, gpointer user_data);
-void artist_get_play_count(const gchar* artist, guint_callback callback, gpointer user_data);
+void artist_get_listener_count(const gchar* artist, uint_callback callback, gpointer user_data);
+void artist_get_play_count(const gchar* artist, uint_callback callback, gpointer user_data);
 void artist_get_published_date_time(const gchar* artist, date_time_callback callback, gpointer user_data);
 void artist_get_summary(const gchar* artist, utf8_callback callback, gpointer user_data);
 void artist_get_description(const gchar* artist, utf8_callback callback, gpointer user_data);</diff>
      <filename>artist.h</filename>
    </modified>
    <modified>
      <diff>@@ -2,9 +2,11 @@
 #include &quot;communication.h&quot;
 #include &quot;authentication.h&quot;
 	
+#define TOKEN_NOT_GRANTED 8
+
 const lfmmethod authentication_method_declarations[] = 
 {
-	{&quot;auth.getToken&quot;, {}}
+	{&quot;auth.getToken&quot;, {}, {{TOKEN_NOT_GRANTED, &quot;There was an error granting the request token. Please try again later.&quot;},{0, NULL}}}
 };
 
 //enum has to be index of declarations
@@ -29,12 +31,18 @@ void authentication_get_token(utf8_callback callback, gpointer user_data)
 	get_info_with_parameters(&amp;primary_methods[AUTHENTICATION_GET_TOKEN], callback, user_data, NULL);
 }
 
-void get_authtoken(gchar* token, guint token_size, GError* error)
+struct authenticate_data
+{
+	boolean_callback callback;
+	gpointer user_data;
+};
+
+void get_authtoken(const gchar* token, guint token_size, gpointer user_data, GError* error)
 {
 	token_request_authorization(token, token_size);
 } 
 
-void authenticate()
+void authenticate(gpointer user_data)
 {
-	authentication_get_token(get_authtoken, NULL);
+	authentication_get_token(get_authtoken, user_data);
 }</diff>
      <filename>authentication.c</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@
 #include &lt;glib.h&gt;
 #include &quot;callback.h&quot;
 
-void authenticate();
+void authenticate(gpointer user_data);
 void authentication_get_token(utf8_callback callback, gpointer user_data);
 
 #endif /*AUTHENTICATION_H_*/</diff>
      <filename>authentication.h</filename>
    </modified>
    <modified>
      <diff>@@ -4,18 +4,18 @@
 #include &lt;glib.h&gt;
 #include &quot;lfmobjects.h&quot;
 
-typedef void (*utf8_callback)(gchar* utf8, guint utf8_length, GError* error);
-typedef void (*url_callback)(gchar** url, guint* url_length, GError** error);
-typedef void (*guint_callback)(guint digit, GError** error);
-typedef void (*boolean_callback)(gboolean istrue, GError** error);
-typedef void (*artists_callback)(lfmartist** artists, GError** error);
-typedef void (*tags_callback)(lfmtag** tags, GError** error);
-typedef void (*tracks_callback)(lfmtrack** tracks, GError** error);
+typedef void (*utf8_callback)(const gchar* utf8, guint utf8_length, gpointer user_data, GError* error);
+typedef void (*url_callback)(const gchar* url, guint* url_length,  gpointer user_data, GError* error);
+typedef void (*uint_callback)(guint digit, gpointer user_data, GError* error);
+typedef void (*boolean_callback)(gboolean istrue, gpointer user_data, GError* error);
+typedef void (*artists_callback)(lfmartist** artists, gpointer user_data, GError* error);
+typedef void (*tags_callback)(lfmtag** tags,  gpointer user_data, GError* error);
+typedef void (*tracks_callback)(lfmtrack** tracks,  gpointer user_data, GError* error);
 
-typedef void (*date_time_callback)(GTimeVal date_time, GError** error);
+typedef void (*date_time_callback)(GTimeVal date_time, gpointer user_data, GError* error);
 
-typedef void (*albums_callback)(lfmalbum** albums, GError** error);
-typedef void (*events_callback)(lfmevent** events, GError** error);
-typedef void (*users_callback)(lfmuser** users, GError** error);
+typedef void (*albums_callback)(lfmalbum** albums,  gpointer user_data, GError* error);
+typedef void (*events_callback)(lfmevent** events,  gpointer user_data, GError* error);
+typedef void (*users_callback)(lfmuser** users,  gpointer user_data, GError* error);
 
 #endif /*CALLBACK_H_*/</diff>
      <filename>callback.h</filename>
    </modified>
    <modified>
      <diff>@@ -3,19 +3,30 @@
 #include &lt;curl/curl.h&gt;
 #include &quot;include.h&quot; 
 #include &quot;communication.h&quot;
-
-static const gchar* api_key = &quot;100780b228c8aa69be51d709572b45b8&quot;;
-static const gchar* secret = &quot;ba296e6c0de47df63b43d4410a702626&quot;;
-static const gchar* webservice_url = &quot;http://ws.audioscrobbler.com/2.0/&quot;;
-
-static const gchar* get_api_key()
-{
-	return api_key;
-}
+#include &quot;lfmobjects.h&quot;
+
+#define API_KEY &quot;100780b228c8aa69be51d709572b45b8&quot;
+#define SECRET &quot;ba296e6c0de47df63b43d4410a702626&quot;
+#define WEBSERVICE_URL &quot;http://ws.audioscrobbler.com/2.0/&quot;
+
+lfmerror general_errors[] =
+{
+	{INVALID_SERVICE,       &quot;Invalid service -This service does not exist&quot;},
+	{INVALID_METHOD,        &quot;Invalid Method - No method with that name in this package&quot;},
+    {AUTHENTICATION_FAILED, &quot;Authentication Failed - You do not have permissions to access the service&quot;},
+    {INVALID_FORMAT,        &quot;Invalid format - This service doesn't exist in that format&quot;},
+    {INVALID_PARAMETERS,    &quot;Invalid parameters - Your request is missing a required parameter&quot;},
+    {INVALID_RESSOURCE,     &quot;Invalid resource specified&quot;},
+    {INVALID_SESSION,       &quot;Invalid session key - Please re-authenticate&quot;},
+    {INVALID_API,           &quot;Invalid API key - You must be granted a valid key by last.fm&quot;},
+    {SERVICE_OFFLINE,       &quot;Service Offline - This service is temporarily offline. Try again later.&quot;},
+    {SUBSCRIBERS_ONLY,      &quot;Subscribers Only - This service is only available to paid last.fm subscribers&quot;},
+    {0, NULL}	 
+};
 
 gchar* build_url(const gchar* method_name)
 {
-	return g_strdup_printf(&quot;%s?method=%s&amp;api_key=%s&quot;, webservice_url, method_name, get_api_key()); 
+	return g_strdup_printf(WEBSERVICE_URL&quot;?method=%s&amp;api_key=&quot;API_KEY, method_name); 
 }
 
 gchar* build_request_url(const gchar* method_name)
@@ -25,12 +36,17 @@ gchar* build_request_url(const gchar* method_name)
 
 gchar* build_post_url()
 {
-	return g_strdup(webservice_url);
+	return WEBSERVICE_URL;
 }
 
+EMBED_PRINT_FUNCTIONS(token, &quot;Token&quot;)
+
+#define TOKEN_UNAUTHORIZED 14
+#define TOKEN_EXPIRED 15
+
 const lfmmethod token_method_declarations[] = 
 {
-	{&quot;auth.getsession&quot;, {{&quot;token&quot;, NULL, FALSE}}}
+	{&quot;auth.getSession&quot;, {{&quot;token&quot;, NULL, FALSE}}, {{AUTHENTICATION_FAILED, &quot;Invalid authentication token supplied&quot;},{TOKEN_UNAUTHORIZED, &quot;This token has not been authorized&quot;},{TOKEN_EXPIRED, &quot;This token has expired&quot;},{0, NULL}}}
 };
 
 enum token_method
@@ -59,7 +75,7 @@ void session_get_name(const gchar* token, utf8_callback callback, gpointer user_
 
 void session_get_key(const gchar* token, utf8_callback callback, gpointer user_data)
 {
-	get_info_with_parameters(token, &amp;token_data_declarations[SESSION_KEY], callback, user_data, token, NULL);
+	get_info_with_parameters(&amp;token_data_declarations[SESSION_KEY], callback, user_data, token, NULL);
 }
 
 void session_is_subscriber(const gchar* token, boolean_callback callback, gpointer user_data)
@@ -67,16 +83,16 @@ void session_is_subscriber(const gchar* token, boolean_callback callback, gpoint
 	get_info_with_parameters(&amp;token_data_declarations[SESSION_IS_SUBSCRIBER], callback, user_data, token, NULL);
 }	
 
-gboolean token_request_authorization(gchar* token, guint token_size)
+void token_request_authorization(const gchar* token, guint token_size)
 {
 	createv(gchar, argv);
 	addv(gchar, argv, &quot;x-www-browser&quot;);
-	addv(gchar, argv, g_strdup_printf(&quot;http://www.last.fm/api/auth/?api_key=%s&amp;token=%s&quot;, get_api_key(), token));
+	addv(gchar, argv, g_strdup_printf(&quot;http://www.last.fm/api/auth/?api_key=&quot;API_KEY&quot;&amp;token=%s&quot;, token));
 	
 	gint exit_status = 0;
 	
 	GError* error = NULL;
-	gboolean success = g_spawn_sync
+	g_spawn_sync
 		(
 			NULL, //working directory
 			argv,
@@ -89,10 +105,15 @@ gboolean token_request_authorization(gchar* token, guint token_size)
 			&amp;exit_status,
 			&amp;error
 		);
+		
+	if(error)
+	{
+		token_printerr(error-&gt;message);
+		g_error_free(error);		
+	}
 	
 	g_free(argv[1]);
 	g_free(argv);
-	return success;
 }
 
 const gchar* token_get_session(const gchar* token)
@@ -120,10 +141,42 @@ const gchar* token_get_session(const gchar* token)
 
 void token_get_signature(const gchar* token, const gchar* method_name)
 {
-	gchar* string = g_strdup_printf(&quot;api_key%stoken%smethod%s&quot;, api_key, token, method_name);
+	gchar* string = g_strdup_printf(&quot;api_key&quot;API_KEY&quot;token%smethod%s&quot;SECRET, token, method_name);
 	//gchar* signature = md5();
 	g_free(string);
 }
+
+//
+//Simple parser
+//
+
+gboolean parse_boolean(const gchar* boolean, size_t user_size, GError** error)
+{
+	return TRUE;
+}
+
+guint parse_uint(const gchar* user, size_t user_size, GError** error)
+{
+	return 0;
+}
+
+GTimeVal parse_date_time(const gchar* date_time, size_t date_time_size, GError** error)
+{
+	GTimeVal test;
+	return test;
+	//return utf82date(date_time);
+}
+
+struct xml_parser
+{
+	const lfmget* call;
+	guint in_level;
+	gpointer callback;
+	gpointer user_data;
+	gchar** texts;
+	size_t* text_lengths;
+};
+
 void xml_parse_start
 (
 	GMarkupParseContext* context,
@@ -133,7 +186,13 @@ void xml_parse_start
 	gpointer             user_data,
 	GError**             error
 )
-{
+{	
+	struct xml_parser* parser = user_data;
+	
+	const gchar* criteria_name = parser-&gt;call-&gt;path[parser-&gt;in_level];
+
+	if(strcmp(element_name, criteria_name) == 0)
+		parser-&gt;in_level++;
 }
 
 // Called for close tags &lt;/foo&gt;
@@ -145,6 +204,182 @@ void xml_parse_end
 	GError**             error
 )
 {
+	struct xml_parser* parser = user_data;
+	
+	const gchar* criteria_name = parser-&gt;call-&gt;path[parser-&gt;in_level - 1];
+
+	if(strcmp(element_name, criteria_name) != 0)
+		return;
+	
+	parser-&gt;in_level--;
+	
+	guint* uint_iterator = parser-&gt;text_lengths;
+	guint text_len = 0;
+	
+	while(*uint_iterator != 0)
+	{
+		text_len += *uint_iterator;
+		uint_iterator++;
+	}
+	
+	gchar* text = NULL;
+	
+	if(!error)
+	{
+		if(text_len == 0)
+		{
+			//nothing found
+			*error = g_error_new_literal(0, 1, &quot;No data delivered&quot;);
+		}
+		else
+		{
+			text = g_alloca(text_len);
+			gchar* current_collected = text; 
+	
+			gchar** iterator = parser-&gt;texts;
+			uint_iterator = parser-&gt;text_lengths;
+	
+			while(*iterator)
+			{
+				strncpy(current_collected, *iterator, *uint_iterator);
+				current_collected += *uint_iterator;
+				iterator++;
+				uint_iterator++;
+			}
+		}
+	}
+	
+	gpointer callback = parser-&gt;callback;
+	gpointer callback_user_data = parser-&gt;user_data;
+	
+	//we arrived	
+	switch(parser-&gt;call-&gt;data_parser)
+	{		
+		case DATA_DATE_TIME:
+		{
+			GTimeVal dt;
+			
+			if(error)
+			{
+				dt.tv_sec = 0;
+				dt.tv_usec = 0;
+			}	
+			else
+				dt = parse_date_time(text, text_len, error);
+						
+			((date_time_callback)callback)(dt, callback_user_data, *error);
+			break;
+		}
+		case DATA_BOOLEAN:
+		{
+			gboolean success = FALSE;
+			
+			if(!error)
+				success = parse_boolean(text, text_len, error); 
+			
+			((boolean_callback)callback)(success, callback_user_data, *error);
+			break;
+		}
+		case DATA_UINT:
+		{
+			guint result = 0;
+			
+			if(!error)
+				result = parse_uint(text, text_len, error);
+			
+			((uint_callback)callback)(result, callback_user_data, *error);
+			break;
+		}
+		case DATE_EVENTS:
+		{
+			lfmevent** events = NULL;
+			
+			if(!error)
+				events = parse_events(text, text_len, error);
+				
+			((events_callback)callback)(events, callback_user_data, *error);
+			
+			destroyv(lfmevent, events);
+			break;
+		}
+		case DATA_ARTISTS:
+		{
+			lfmartist** artists = NULL;
+			
+			if(!error)
+				artists = parse_artists(text, text_len, error);
+				
+			((artists_callback)callback)(artists, callback_user_data, *error);
+			
+			destroyv(lfmartist, artists);
+			break;
+		}		
+		case DATA_ALBUMS:
+		{
+			lfmalbum** albums = NULL;
+			
+			if(!error)
+				albums = parse_albums(text, text_len, error);
+				
+			((albums_callback)callback)(albums, callback_user_data, *error);
+			
+			destroyv(lfmalbum, albums);
+			break;
+		}
+		case DATA_USERS:
+		{
+			lfmuser** users = NULL;
+			
+			if(!error)
+				users = parse_users(text, text_len, error);
+				
+			((users_callback)callback)(users, callback_user_data, *error);
+			
+			destroyv(lfmuser, users);
+			break;
+		}
+		case DATA_TAGS:
+		{
+			lfmtag** tags = NULL;
+			
+			if(!error)
+				tags = parse_tags(text, text_len, error);
+				
+			((tags_callback)callback)(tags, callback_user_data, *error);
+			
+			destroyv(lfmtag, tags);
+			break;
+		}
+		case DATA_TRACKS:
+		{
+			lfmtrack** tracks = NULL;
+			
+			if(!error)
+				tracks = parse_tracks(text, text_len, error);
+				
+			((tracks_callback)callback)(tracks, callback_user_data, *error);
+			
+			destroyv(lfmtrack, tracks);
+			break;
+		}
+		default: //DATA_UTF8 OR DATA_URL
+		{
+			((utf8_callback)callback)(text, text_len, callback_user_data, *error);
+			break;
+		}
+	}
+	
+	gchar** iterator = parser-&gt;texts;	
+	
+	while(*iterator)
+	{
+		g_free(*iterator);		
+		iterator++;		
+	}
+	
+	*parser-&gt;texts = NULL;
+	*parser-&gt;text_lengths = 0;
+	
 }
 
 // Called for character data
@@ -159,6 +394,25 @@ void xml_parse_text
 	GError**             error
 )
 {
+	struct xml_parser* parser = user_data;
+	
+	if(countv((void**)parser-&gt;call-&gt;path) != (parser-&gt;in_level))
+		return; //not in desired structure
+	
+	addv(gchar, parser-&gt;texts,  g_memdup(text, text_len));
+	
+	size_t* iterator = parser-&gt;text_lengths;
+	
+	size_t count = 0;
+	while(*iterator != 0)
+	{
+		count++;
+		iterator++;
+	}
+	
+	parser-&gt;text_lengths = g_renew(size_t, parser-&gt;text_lengths, count += 2);		
+	parser-&gt;text_lengths[count - 2] = text_len;
+	parser-&gt;text_lengths[count - 1] = 0;		
 }
 
 // Called for strings that should be re-saved verbatim in this same
@@ -270,6 +524,10 @@ lfmproxy* proxy_init()
 	
 	//startup process thread 
 	GError* error = NULL;
+	
+	if(!g_thread_supported())
+		g_thread_init(NULL);
+
 	GThread* thread = g_thread_create_full
 		(
 			proxy_process,
@@ -289,11 +547,13 @@ void proxy_destroy(lfmproxy* proxy)
 	if(!proxy)
 		return;
 		
+	proxy_end_process(proxy);
+		
 	CURLMcode code = curl_multi_cleanup(proxy-&gt;multi_handle);
 	g_free(proxy);
 }
 
-size_t parse_xml( void *ptr, size_t size, size_t nmemb, void *stream)
+size_t parse_xml(void *ptr, size_t size, size_t nmemb, void *stream)
 {
 	gchar* utf8 = ptr;
 	
@@ -308,20 +568,30 @@ size_t parse_xml( void *ptr, size_t size, size_t nmemb, void *stream)
 	return 0;
 }
 
-void proxy_request(lfmproxy* proxy, const lfmmethod* method, lfmparametervalue** parameters, void* callback, void* user_data)
+void proxy_request(lfmproxy* proxy, const lfmget* call, lfmparametervalue** parameters, gpointer callback, gpointer user_data)
 {
 	CURL* easy_handle = curl_easy_init();
 	
-	gchar* url = build_request_url(method-&gt;name);
+	gchar* url = build_request_url(call-&gt;method-&gt;name);
 	CURLcode code = curl_easy_setopt(easy_handle, CURLOPT_URL, url);
 	code = curl_easy_setopt(easy_handle, CURLOPT_HTTPGET, TRUE);
 	
+	struct xml_parser* parser = g_new(struct xml_parser, 1);
+	parser-&gt;call = call;
+	parser-&gt;in_level = 0;
+	parser-&gt;callback = callback;
+	parser-&gt;user_data = user_data;
+	parser-&gt;texts = g_new(gchar*, 1);
+	*parser-&gt;texts = NULL;
+	parser-&gt;text_lengths = g_new(size_t, 1);
+	*parser-&gt;text_lengths = 0;
+	
 	//create new parse context
 	GMarkupParseContext* context = g_markup_parse_context_new
 		(
 			&amp;proxy-&gt;parser,
 			0, //GMarkupParseFlags
-			NULL, //user_data
+			parser, //user_data
 			NULL //GDestroyNotify
 		);	
 
@@ -337,7 +607,7 @@ void proxy_request(lfmproxy* proxy, const lfmmethod* method, lfmparametervalue**
 
 void proxy_post(lfmproxy* proxy, const gchar* method_name, gchar** names, gchar** values)
 {	
-	gchar** post = g_strdup_printf(&quot;method=%s&amp;api_key=%s&quot;, method_name, get_api_key());
+	gchar* post = g_strdup_printf(&quot;method=%s&amp;api_key=&quot;API_KEY, method_name);
 	
 	gchar** name_iterator = names;
 	gchar** value_iterator = values;
@@ -411,16 +681,26 @@ void proxy_post(lfmproxy* proxy, const gchar* method_name, gchar** names, gchar*
 	code = curl_multi_add_handle(proxy-&gt;multi_handle, easy_handle);
 }
 
-static lfmproxy process_proxy;
+static lfmproxy* process_proxy;
 
 static lfmproxy* get_proxy()
 {
-	return &amp;process_proxy;
+	return process_proxy;
+}
+
+void communication_init()
+{
+	process_proxy = proxy_init();
 }
 
-void get_data_from_method(lfmmethod const * method, lfmparametervalue** parameter, void* callback, void* user_data)
+void communication_destroy()
+{
+	proxy_destroy(process_proxy);
+}
+
+void get_data_from_method(const lfmget* call, lfmparametervalue** parameter, void* callback, void* user_data)
 {	
-	proxy_request(get_proxy(), method, parameter, callback, user_data);
+	proxy_request(get_proxy(), call, parameter, callback, user_data);
 }
 
 void send_data_to_method(const gchar* method_name, gchar** names, gchar** values)
@@ -428,11 +708,6 @@ void send_data_to_method(const gchar* method_name, gchar** names, gchar** values
 	proxy_post(get_proxy(), method_name, names, values);
 }
 
-gpointer parse_utf8(const gchar* string, gpointer user_data, GError** error)
-{
-	return g_strdup(string);
-}
-
 void fill_parameters(lfmparametervalue** values, const lfmmethod* method, va_list vl)
 {	
 	lfmparameter const * iterator = method-&gt;parameters;
@@ -451,7 +726,6 @@ void fill_parameters(lfmparametervalue** values, const lfmmethod* method, va_lis
 		 lfmparametervalue* value = g_new(lfmparametervalue, 1);
 		 value-&gt;name = iterator-&gt;name;
 		 value-&gt;value = output;
-		 value-&gt;value_length = output_length;
 		 addv(lfmparametervalue, values, value);
 		 	
 		 iterator++;
@@ -477,34 +751,6 @@ void guint2utf8(void* array, gchar** utf8, size_t* byte_count)
 {
 }
 
-GDate* utf82date(const char* date_string)
-{
-	GDate* date = g_date_new;
-	g_date_set_parse(date, date_string);
-}
-
-gboolean parse_boolean(const gchar* user, size_t user_size, GError** error)
-{
-	return TRUE;
-}
-
-guint parse_uint(const gchar* user, size_t user_size, GError** error)
-{
-	return 0;
-}
-
-gchar* parse_url(const gchar* user, size_t user_size, GError** error)
-{
-	return NULL;
-}
-
-GTimeVal parse_date_time(const gchar* date_time, size_t date_time_size, GError** error)
-{
-	GTimeVal test;
-	return test;
-	//return utf82date(date_time);
-}
-
 G_GNUC_NULL_TERMINATED void get_info_with_parameters(const lfmget* call, gpointer callback, gpointer user_data, ...)
 {	
 	createv(lfmparametervalue, parameters);
@@ -514,7 +760,7 @@ G_GNUC_NULL_TERMINATED void get_info_with_parameters(const lfmget* call, gpointe
 	
 	fill_parameters(parameters, call-&gt;method, vl);
 	
-	get_data_from_method(call-&gt;method, parameters, callback, user_data);
+	get_data_from_method(call, parameters, callback, user_data);
 	
 	va_end(vl);
 	destroyv(lfmparametervalue, parameters);
@@ -541,36 +787,7 @@ void parse_start
 	GError**             error
 )
 {
-	lfmelement* element_ref = user_data;
 	
-	if(element_ref-&gt;is_in_element)
-		return;
-	
-	if(strcmp(element_ref-&gt;name, element_name) == 0)
-	{
-		if(element_ref-&gt;attribute)
-		{
-			gchar** iterator = attribute_names;
-			guint index = 0;
-			
-			while(*iterator)
-			{
-				if
-				(
-					strcmp(*iterator, element_ref-&gt;attribute) == 0
-				 	&amp;&amp; strcmp(attribute_values[index], element_ref-&gt;value) == 0
-				)
-				{
-					element_ref-&gt;is_in_element = TRUE;
-					break;					
-				}
-				
-				index++;
-			}
-		}
-		else
-			element_ref-&gt;is_in_element = TRUE;
-	}	
 }
 
 void parse_end
@@ -581,13 +798,7 @@ void parse_end
 	GError**             error
 )
 {
-	lfmelement* element_ref = user_data;
-	
-	if(!element_ref-&gt;is_in_element)
-		return;
-	
-	if(strcmp(element_ref-&gt;name, element_name) == 0)
-		element_ref-&gt;is_in_element = FALSE;
+
 }
 
 void parse_text
@@ -598,14 +809,7 @@ void parse_text
 	gpointer             user_data,
 	GError**             error
 )
-{
-	lfmelement* element_ref = user_data;
-	
-	element_ref-&gt;inner_string_length += text_len;	
-	
-	element_ref-&gt;inner_string = g_renew(gchar, element_ref-&gt;inner_string, inner_string_length);
-	
-	g_memmove(element_ref-&gt;inner_string[element_ref-&gt;inner_string_length - text_len], text, text_len * sizeof(gchar));	
+{	
 }
 
 void album_add_tags(const lfmalbum* album, gchar* tags[10])</diff>
      <filename>communication.c</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,31 @@
 #include &lt;glib.h&gt;
 #include &quot;callback.h&quot;
 
+void communication_init();
+void communication_destroy();
+
+struct lfmerror
+{
+	const guint code;
+	const gchar* message;
+};
+
+typedef struct lfmerror lfmerror;
+
+enum lfmgeneralerrorcode
+{
+	INVALID_SERVICE       = 2,
+    INVALID_METHOD        = 3,
+    AUTHENTICATION_FAILED = 4,
+    INVALID_FORMAT        = 5,
+    INVALID_PARAMETERS    = 6,
+    INVALID_RESSOURCE     = 7,
+    INVALID_SESSION       = 9,
+    INVALID_API           = 10,
+    SERVICE_OFFLINE       = 11,
+    SUBSCRIBERS_ONLY      = 12
+};
+
 struct lfmproxy;
 typedef struct lfmproxy lfmproxy;
 
@@ -24,22 +49,13 @@ typedef struct lfmproxy lfmproxy;
 //
 //Token functions
 //
-gboolean token_request_authorization(gchar* token, guint token_size);	
-	/*
-enum refid
-{
-	PRIMARY_ID   = 1 &lt;&lt; 0,
-	SECONDARY_ID = 1 &lt;&lt; 1,
-	ANY_ID = PRIMARY_ID | SECONDARY_ID
-};
-typedef enum refid refid;
-*/
+void token_request_authorization(const gchar* token, guint token_size);	
 
 typedef void (*type_converter)(void* type, gchar** utf8, guint* utf8_length);
 
 struct lfmparameter
 {
-	gchar* name;
+	const gchar* name;
 	type_converter converter;
 	gboolean is_optional;
 };
@@ -49,7 +65,8 @@ typedef struct lfmparameter lfmparameter;
 struct lfmmethod
 {
 	const gchar* name;
-	const lfmparameter parameters[2];	
+	const lfmparameter parameters[2];
+	const lfmerror specific_errors[5];	
 };
 
 enum data_type
@@ -80,12 +97,8 @@ typedef struct lfmget lfmget;
 
 struct lfmparametervalue
 {
-	//null terminated
-	gchar* name;
-	
-	//not null terminatd
-	gchar* value;
-	guint value_length; 
+	const gchar* name;
+	const gchar* value;
 };
 
 typedef struct lfmparametervalue lfmparametervalue;
@@ -95,7 +108,7 @@ void guint2utf8(void* array, gchar** utf8, size_t* byte_count);
 
 void fill_parameters(lfmparametervalue** values, const lfmmethod* method, va_list vl);
 
-void get_data_from_method(lfmmethod const * method, lfmparametervalue** parameter, void* callback, void* user_data);
+void get_data_from_method(const lfmget* call, lfmparametervalue** parameter, void* callback, void* user_data);
 G_GNUC_NULL_TERMINATED void get_info_with_parameters(const lfmget* call, gpointer callback, gpointer user_data, ...);
 
 #endif /*COMMUNICATION_H_*/</diff>
      <filename>communication.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,23 @@
 #include &quot;lastfm.h&quot;
 
-int main(int argc, const char* args[])
+static GCond* cond = NULL; 
+
+void mbid(const gchar* mchar, size_t msize, gpointer user_data, GError* error)
 {
-	authenticate();
+	g_cond_broadcast(cond);
+}
+
+int main(int argc, const char* args[])
+{	
+	lastfm_init();
+	cond = g_cond_new();
+	artist_get_musicbrainz_id(&quot;cher&quot;, mbid, NULL);
+	
+	GMutex* mutex = g_mutex_new();   
+	g_cond_wait(cond, mutex);
+	
+	g_cond_free(cond);
+	lastfm_destroy();
+	
 	return 0;
 }</diff>
      <filename>lastfm.c</filename>
    </modified>
    <modified>
      <diff>@@ -5,4 +5,10 @@
 #include &quot;album.h&quot;
 #include &quot;artist.h&quot;
 
+//
+//Before doing anything with the library the init functions have to be called
+//
+void lastfm_init();
+void lastfm_destroy();
+
 #endif /*LASTFM_H_*/</diff>
      <filename>lastfm.h</filename>
    </modified>
    <modified>
      <diff>@@ -5,27 +5,27 @@ lfmuser** parse_users(const gchar* user, size_t user_size, GError** error)
 	return NULL;
 }
 
-lfmevent** parse_events(const gchar* user, size_t user_size, GError** error)
+lfmevent** parse_events(const gchar* events, size_t user_size, GError** error)
 {
 	return NULL;
 }
 
-lfmartist** parse_artists(const gchar* user, size_t user_size, GError** error)
+lfmartist** parse_artists(const gchar* artists, size_t user_size, GError** error)
 {
 	return NULL;
 }
 
-lfmtag** parse_tags(const gchar* user, size_t user_size, GError** error)
+lfmtag** parse_tags(const gchar* tags, size_t user_size, GError** error)
 {
 	return NULL;
 }
 
-lfmalbum** parse_albums(const gchar* user, size_t user_size, GError** error)
+lfmalbum** parse_albums(const gchar* albums, size_t user_size, GError** error)
 {
 	return NULL;
 }
 
-lfmtrack** parse_tracks(const gchar* user, size_t user_size, GError** error)
+lfmtrack** parse_tracks(const gchar* tracks, size_t user_size, GError** error)
 {
 	return NULL;
-}
\ No newline at end of file
+}</diff>
      <filename>lfmobjects.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,8 @@
 #ifndef LFMOBJECTS_H_
 #define LFMOBJECTS_H_
 
+#include &lt;glib.h&gt;
+
 struct lfmartist
 {
 };</diff>
      <filename>lfmobjects.h</filename>
    </modified>
    <modified>
      <diff>@@ -0,0 +1,12 @@
+#include &quot;lastfm.h&quot;
+#include &quot;communication.h&quot;
+
+void lastfm_init()
+{
+	communication_init();
+}
+
+void lastfm_destroy()
+{
+	communication_destroy();
+}</diff>
      <filename>liblastfm.c</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>2b8415c9354a98c7bb302eaf3ada037f49a58b0a</id>
    </parent>
  </parents>
  <author>
    <name>LCID Fire</name>
    <email>lcid-fire@gmx.net</email>
  </author>
  <url>http://github.com/LCID-Fire/liblastfm/commit/dc2c374fd650c8b052b95d50e4e912ff78a80429</url>
  <id>dc2c374fd650c8b052b95d50e4e912ff78a80429</id>
  <committed-date>2008-07-08T05:13:04-07:00</committed-date>
  <authored-date>2008-07-08T05:13:04-07:00</authored-date>
  <message>Getting some first simple requests to work</message>
  <tree>c66a4088072e3234ceb163302e842e1cf4da4d09</tree>
  <committer>
    <name>LCID Fire</name>
    <email>lcid-fire@gmx.net</email>
  </committer>
</commit>
