diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index d610734..77687b6 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -40,7 +40,6 @@
 #include "rb-util.h"
 
 #define SESSION_SETTINGS_FILE "sessions"
-#define SESSION_KEY_REQUEST_TIMEOUT 5
 
 struct _RBAudioscrobblerAccountPrivate
 {
@@ -57,13 +56,53 @@ struct _RBAudioscrobblerAccountPrivate
 	GtkWidget *login_status_label;
 	GtkWidget *auth_button;
 
-	/* Timeout notifications */
-	guint session_key_timeout_id;
-
 	/* HTTP requests session */
 	SoupSession *soup_session;
 };
 
+/*
+ * Last.fm  :  http://www.last.fm/api/errorcodes
+ * Libre.fm :  https://git.gnu.io/gnu/gnu-fm/blob/master/nixtape/2.0/index.php 
+ *
+ * Libre.fm ( gnu.fm ) folks keep it a point to be compatible 
+ * with Last.fm error codes. So, we just use Last.fm codes for now.
+
+|  1  -  This error does not exist  |
+|  2  -  Invalid service -This service does not exist  |
+|  3  -  Invalid Method - No method with that name in this package  |
+|  4  -  Authentication Failed - You do not have permissions to access the service  |
+|  5  -  Invalid format - This service doesn't exist in that format  |
+|  6  -  Invalid parameters - Your request is missing a required parameter  |
+|  7  -  Invalid resource specified  |
+|  8  -  Operation failed - Most likely the backend service failed. Please try again.  |
+|  9  -  Invalid session key - Please re-authenticate  |
+| 10  -  Invalid API key - You must be granted a valid key by last.fm  |
+| 11  -  Service Offline - This service is temporarily offline. Try again later.  |
+| 12  -  Subscribers Only - This station is only available to paid last.fm subscribers  |
+| 13  -  Invalid method signature supplied  |
+| 14  -  Unauthorized Token - This token has not been authorized  |
+| 15  -  This item is not available for streaming.  |
+| 16  -  The service is temporarily unavailable, please try again.  |
+| 17  -  Login: User requires to be logged in  |
+| 18  -  Trial Expired - This user has no free radio plays left. Subscription required.  |
+| 19  -  This error does not exist  |
+| 20  -  Not Enough Content - There is not enough content to play this station  |
+| 21  -  Not Enough Members - This group does not have enough members for radio  |
+| 22  -  Not Enough Fans - This artist does not have enough fans for for radio  |
+| 23  -  Not Enough Neighbours - There are not enough neighbours for radio  |
+| 24  -  No Peak Radio - This user is not allowed to listen to radio during peak usage  |
+| 25  -  Radio Not Found - Radio station not found  |
+| 26  -  API Key Suspended - This application is not allowed to make requests to the web services  |
+| 27  -  Deprecated - This type of request is no longer supported  |
+| 29  -  Rate Limit Exceded - Your IP has made too many requests in a short period, exceeding our API guidelines  |
+
+*/
+
+/* Retry only on the following error codes. */
+guint audioscrobbler_retry_error_codes[] = {
+	8, 11, 16
+};
+
 #define RB_AUDIOSCROBBLER_ACCOUNT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_ACCOUNT, RBAudioscrobblerAccountPrivate))
 
 static void          rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass);
@@ -80,6 +119,9 @@ static void	     rb_audioscrobbler_account_set_property (GObject *object,
                                                              const GValue *value,
                                                              GParamSpec *pspec);
 
+static void          update_login_status (RBAudioscrobblerAccount *account,
+					  RBAudioscrobblerAccountLoginStatus login_status);
+
 /* load/save session to file to avoid having to reauthenticate */
 static void          load_session_settings (RBAudioscrobblerAccount *account);
 static void          save_session_settings (RBAudioscrobblerAccount *account);
@@ -90,10 +132,11 @@ static void          request_token (RBAudioscrobblerAccount *account);
 static void          got_token_cb (SoupSession *session,
                                    SoupMessage *msg,
                                    gpointer user_data);
-static gboolean      request_session_key_timeout_cb (gpointer user_data);
+static void          request_session_key (gpointer user_data);
 static void          got_session_key_cb (SoupSession *session,
                                          SoupMessage *msg,
                                          gpointer user_data);
+
 enum
 {
 	PROP_0,
@@ -201,8 +244,6 @@ rb_audioscrobbler_account_init (RBAudioscrobblerAccount *account)
 	account->priv->auth_token = NULL;
 	account->priv->session_key = NULL;
 	account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT;
-
-	account->priv->session_key_timeout_id = 0;
 }
 
 static void
@@ -226,11 +267,6 @@ rb_audioscrobbler_account_dispose (GObject *object)
 		account->priv->service = NULL;
 	}
 
-	if (account->priv->session_key_timeout_id != 0) {
-		g_source_remove (account->priv->session_key_timeout_id);
-		account->priv->session_key_timeout_id = 0;
-	}
-
 	if (account->priv->soup_session != NULL) {
 		soup_session_abort (account->priv->soup_session);
 		g_object_unref (account->priv->soup_session);
@@ -312,6 +348,15 @@ rb_audioscrobbler_account_get_login_status (RBAudioscrobblerAccount *account)
 }
 
 static void
+update_login_status (RBAudioscrobblerAccount *account,
+		     RBAudioscrobblerAccountLoginStatus login_status)
+{
+	account->priv->login_status = login_status;
+	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
+		       0, account->priv->login_status);
+}
+
+static void
 load_session_settings (RBAudioscrobblerAccount *account)
 {
 	/* Attempt to load the saved session */
@@ -345,9 +390,7 @@ load_session_settings (RBAudioscrobblerAccount *account)
 			          account->priv->username,
 			          account->priv->session_key);
 
-		account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN;
-		g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-		               0, account->priv->login_status);
+		update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN);
 	} else {
 		rb_debug ("there is no session to load");
 
@@ -357,9 +400,7 @@ load_session_settings (RBAudioscrobblerAccount *account)
 		g_free (account->priv->session_key);
 		account->priv->session_key = NULL;
 
-		account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT;
-		g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-		               0, account->priv->login_status);
+		update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT);
 	}
 }
 
@@ -438,9 +479,7 @@ rb_audioscrobbler_account_logout (RBAudioscrobblerAccount *account)
 	cancel_session (account);
 	save_session_settings (account);
 
-	account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT;
-	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-	               0, account->priv->login_status);
+	update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT);
 }
 
 void
@@ -454,18 +493,16 @@ rb_audioscrobbler_account_notify_of_auth_error (RBAudioscrobblerAccount *account
 	cancel_session (account);
 	save_session_settings (account);
 
-	account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR;
-	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-	               0, account->priv->login_status);
+	update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR);
 }
 
 static void
 cancel_session (RBAudioscrobblerAccount *account)
 {
 	/* cancels the current session, freeing the username,
-	 * session key, auth token. removing timeout callbacks etc.
-	 * Basically log out without setting state to logged out:
-	 * eg error states will also want to cancel the session
+	 * session key, auth token. Basically log out without 
+	 * setting state to logged out: eg error states will 
+	 * also want to cancel the session
 	 */
 	g_free (account->priv->username);
 	account->priv->username = NULL;
@@ -475,11 +512,6 @@ cancel_session (RBAudioscrobblerAccount *account)
 
 	g_free (account->priv->session_key);
 	account->priv->session_key = NULL;
-
-	if (account->priv->session_key_timeout_id != 0) {
-		g_source_remove (account->priv->session_key_timeout_id);
-		account->priv->session_key_timeout_id = 0;
-	}
 }
 
 static void
@@ -521,9 +553,7 @@ request_token (RBAudioscrobblerAccount *account)
 			            account);
 
 	/* update status */
-	account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN;
-	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-	               0, account->priv->login_status);
+	update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN);
 
 	g_free (sig_arg);
 	g_free (sig);
@@ -560,14 +590,9 @@ got_token_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 				               account->priv->auth_token);
 			rb_debug ("sending user to %s", url);
 			gtk_show_uri (NULL, url, GDK_CURRENT_TIME, NULL);
-
-			/* add timeout which will ask for session key */
-			account->priv->session_key_timeout_id =
-				g_timeout_add_seconds (SESSION_KEY_REQUEST_TIMEOUT,
-					               request_session_key_timeout_cb,
-					               account);
-
 			g_free (url);
+
+			update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_TOKEN_RECEIVED);
 		} else {
 			rb_debug ("error retrieving auth token: %s",
 			          json_object_get_string_member (root_object, "message"));
@@ -581,16 +606,25 @@ got_token_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 
 		cancel_session (account);
 
-		account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR;
-		g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-		               0, account->priv->login_status);
+		update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR);
 	}
 
 	g_object_unref (parser);
 }
 
-static gboolean
-request_session_key_timeout_cb (gpointer user_data)
+void
+rb_audioscrobbler_account_access_granted (gpointer user_data)
+{
+	RBAudioscrobblerAccount *account;
+
+	account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
+
+	/* Request a session key, now we are authenticated. */
+	request_session_key (account);
+}
+
+static void
+request_session_key (gpointer user_data)
 {
 	/* Periodically sends a request for the session key */
 	RBAudioscrobblerAccount *account;
@@ -626,8 +660,6 @@ request_session_key_timeout_cb (gpointer user_data)
 	g_free (sig_arg);
 	g_free (sig);
 	g_free (url);
-
-	return TRUE;
 }
 
 static void
@@ -655,7 +687,7 @@ got_session_key_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 		if (json_object_has_member (root_object, "session")) {
 			JsonObject *session_object;
 
-			/* cancel the old session (and remove timeout) */
+			/* cancel the old session */
 			cancel_session (account);
 
 			session_object = json_object_get_object_member (root_object, "session");
@@ -670,29 +702,43 @@ got_session_key_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 			save_session_settings (account);
 
 			/* update status */
-			account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN;
-			g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-				       0, account->priv->login_status);
+			update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN);
 		} else {
+			int i;
 			int code;
 			const char *message;
+			gboolean retry_error = FALSE;
 
 			code = json_object_get_int_member (root_object, "error");
 			message = json_object_get_string_member (root_object, "message");
 
-			switch (code) {
-			case 14:
-				rb_debug ("auth token has not been authorised yet. will try again");
-				break;
-			default:
-				/* some other error. most likely 4 (invalid token) or 15 (token has expired)
-				 * whatever it is, we wont be retrieving a session key from it
-				 */
-				rb_debug ("error retrieving session key: %s", message);
-
-				/* go back to being logged out */
-				rb_audioscrobbler_account_logout (account);
-				break;
+			rb_debug ("getSession returned ( %d : %s )", code, message);
+			
+			if (code) {
+				/* servers are sometimes busy causing retry errors. */
+				for (i = 0; i < G_N_ELEMENTS (audioscrobbler_retry_error_codes); i++) {
+					if (code == audioscrobbler_retry_error_codes[i]) {
+						retry_error = TRUE;
+						rb_debug ("Received retry error code. will try again");
+						request_session_key (account);
+						
+						break;
+					}
+				}
+
+				if (retry_error == FALSE) {
+					/* whatever it is, we wont be retrieving a session key from it */
+					rb_debug ("error retrieving session key. logging out");
+
+					/* go back to being logged out */
+					rb_audioscrobbler_account_logout (account);
+
+					/* This is just here atleast to say that login failed, 
+					 * rather than not saying anything. It should contain the
+					 * exact error message.
+					 */
+					update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR);
+				}
 			}
 		}
 
@@ -702,9 +748,7 @@ got_session_key_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
 
 		cancel_session (account);
 
-		account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR;
-		g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
-		               0, account->priv->login_status);
+		update_login_status (account, RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR);
 	}
 
 	g_object_unref (parser);
@@ -722,6 +766,7 @@ rb_audioscrobbler_account_login_status_get_type (void)
 		static const GEnumValue values[] = {
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT, "Logged out"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN, "Logging in"),
+			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_TOKEN_RECEIVED, "Authentication token received"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN, "Logged in"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR, "Authentication Error"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR, "Connection Error"),
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.h b/plugins/audioscrobbler/rb-audioscrobbler-account.h
index 1575725..7159d64 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.h
@@ -39,6 +39,7 @@ typedef enum
 {
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT,
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN,
+	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_TOKEN_RECEIVED,
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN,
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR,
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_CONNECTION_ERROR
@@ -80,6 +81,7 @@ const char *                       rb_audioscrobbler_account_get_username (RBAud
 const char *                       rb_audioscrobbler_account_get_session_key (RBAudioscrobblerAccount *account);
 RBAudioscrobblerAccountLoginStatus rb_audioscrobbler_account_get_login_status (RBAudioscrobblerAccount *account);
 
+void                            rb_audioscrobbler_account_access_granted (gpointer user_data);
 void                            rb_audioscrobbler_account_authenticate (RBAudioscrobblerAccount *account);
 void                            rb_audioscrobbler_account_logout (RBAudioscrobblerAccount *account);
 void                            rb_audioscrobbler_account_notify_of_auth_error (RBAudioscrobblerAccount *account);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
index 9e6bca0..3c62c55 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
@@ -73,6 +73,7 @@ struct _RBAudioscrobblerProfilePagePrivate {
 	/* Login related UI */
 	GtkWidget *login_bar;
 	GtkWidget *login_status_label;
+	GtkWidget *login_continue_button;
 	GtkWidget *login_response_button;
 
 	/* Profile UI */
@@ -509,12 +510,18 @@ init_login_ui (RBAudioscrobblerProfilePage *page)
 
 	page->priv->login_bar = gtk_info_bar_new ();
 	page->priv->login_status_label = gtk_label_new ("");
-	page->priv->login_response_button = gtk_button_new ();
+	
 	content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (page->priv->login_bar));
 	gtk_container_add (GTK_CONTAINER (content_area), page->priv->login_status_label);
+
+	page->priv->login_continue_button =
+		gtk_info_bar_add_button (GTK_INFO_BAR (page->priv->login_bar),
+		                         "Continue", GTK_RESPONSE_ACCEPT);
 	page->priv->login_response_button =
 		gtk_info_bar_add_button (GTK_INFO_BAR (page->priv->login_bar),
 		                         "", GTK_RESPONSE_OK);
+	
+	gtk_widget_hide (page->priv->login_continue_button);
 	g_signal_connect (page->priv->login_bar,
 	                  "response",
 	                  G_CALLBACK (login_bar_response_cb),
@@ -710,6 +717,12 @@ login_bar_response_cb (GtkInfoBar *info_bar,
                        gint response_id,
                        RBAudioscrobblerProfilePage *page)
 {
+	/* Process 'Access granted' action */
+	if (response_id == GTK_RESPONSE_ACCEPT) {
+		rb_audioscrobbler_account_access_granted (page->priv->account);
+		return;
+	}
+	
 	switch (rb_audioscrobbler_account_get_login_status (page->priv->account)) {
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT:
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR:
@@ -717,6 +730,7 @@ login_bar_response_cb (GtkInfoBar *info_bar,
 		rb_audioscrobbler_account_authenticate (page->priv->account);
 		break;
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN:
+	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_TOKEN_RECEIVED:
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN:
 		rb_audioscrobbler_account_logout (page->priv->account);
 		break;
@@ -744,6 +758,7 @@ login_status_change_cb (RBAudioscrobblerAccount *account,
 	char *button_text = NULL;
 	gboolean show_login_bar;
 	gboolean show_profile;
+	gboolean show_continue_button = FALSE;
 
 	username = rb_audioscrobbler_account_get_username (page->priv->account);
 	session_key = rb_audioscrobbler_account_get_session_key (page->priv->account);
@@ -799,6 +814,14 @@ login_status_change_cb (RBAudioscrobblerAccount *account,
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN:
 		show_login_bar = TRUE;
 		show_profile = FALSE;
+		label_text = g_strdup (_("Connecting to server..."));
+		button_text = g_strdup (_("Cancel"));
+		gtk_info_bar_set_message_type (GTK_INFO_BAR (page->priv->login_bar), GTK_MESSAGE_INFO);
+		break;
+	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_TOKEN_RECEIVED:
+		show_login_bar = TRUE;
+		show_profile = FALSE;
+		show_continue_button = TRUE;
 		label_text = g_strdup (_("Waiting for authentication..."));
 		button_text = g_strdup (_("Cancel"));
 		gtk_info_bar_set_message_type (GTK_INFO_BAR (page->priv->login_bar), GTK_MESSAGE_INFO);
@@ -844,6 +867,12 @@ login_status_change_cb (RBAudioscrobblerAccount *account,
 		gtk_widget_hide (page->priv->profile_window);
 	}
 
+	if (show_continue_button == TRUE) {
+		gtk_widget_show_all (page->priv->login_continue_button);
+	} else {
+		gtk_widget_hide (page->priv->login_continue_button);
+	}
+
 	g_free (label_text);
 	g_free (button_text);
 }
