Index: protocols/twitter/twitter_lib.c
===================================================================
--- protocols/twitter/twitter_lib.c	(revision 9f03c472fef309878ff2f3bc720d51e6d03077f1)
+++ protocols/twitter/twitter_lib.c	(revision 3f44e4339db4e6e97260e864ecb56321d379e74b)
@@ -36,5 +36,5 @@
 #include "base64.h"
 #include "twitter_lib.h"
-#include "json_util.h"
+#include "parson.h"
 #include <ctype.h>
 #include <errno.h>
@@ -64,4 +64,8 @@
 	gboolean from_filter;
 };
+
+#define JSON_O_FOREACH(o, k, v) \
+    const char *k; const JSON_Value *v; int __i; \
+    for (__i = 0; json_object_get_tuple(o, __i, &k, &v); __i++)
 
 /**
@@ -166,5 +170,5 @@
 {
 	static char *ret = NULL;
-	json_value *root, *err;
+	JSON_Value *root, *err;
 
 	g_free(ret);
@@ -172,9 +176,10 @@
 
 	if (req->body_size > 0) {
-		root = json_parse(req->reply_body, req->body_size);
-		err = json_o_get(root, "errors");
-		if (err && err->type == json_array && (err = err->u.array.values[0]) &&
-		    err->type == json_object) {
-			const char *msg = json_o_str(err, "message");
+		root = json_parse_string(req->reply_body);
+		err = json_object_get_value(json_object(root), "errors");
+		if (err && json_type(err) == JSONArray &&
+		    (err = json_array_get_value(json_array(err), 0)) &&
+		    json_type(err) == JSONObject) {
+			const char *msg = json_object_get_string(json_object(err), "message");
 			if (msg) {
 				ret = g_strdup_printf("%s (%s)", req->status_string, msg);
@@ -189,10 +194,10 @@
 /* WATCH OUT: This function might or might not destroy your connection.
    Sub-optimal indeed, but just be careful when this returns NULL! */
-static json_value *twitter_parse_response(struct im_connection *ic, struct http_request *req)
+static JSON_Value *twitter_parse_response(struct im_connection *ic, struct http_request *req)
 {
 	gboolean logging_in = !(ic->flags & OPT_LOGGED_IN);
 	gboolean periodic;
 	struct twitter_data *td = ic->proto_data;
-	json_value *ret;
+	JSON_Value *ret;
 	char path[64] = "", *s;
 
@@ -232,5 +237,5 @@
 	}
 
-	if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) {
+	if ((ret = json_parse_string(req->reply_body)) == NULL) {
 		imcb_error(ic, "Could not retrieve %s: %s",
 		           path, "XML parse error");
@@ -289,7 +294,7 @@
  * Fill a list of ids.
  */
-static gboolean twitter_xt_get_friends_id_list(json_value *node, struct twitter_xml_list *txl)
-{
-	json_value *c;
+static gboolean twitter_xt_get_friends_id_list(JSON_Value *node, struct twitter_xml_list *txl)
+{
+	JSON_Array *c;
 	int i;
 
@@ -297,21 +302,18 @@
 	txl->type = TXL_ID;
 
-	c = json_o_get(node, "ids");
-	if (!c || c->type != json_array) {
+	if (!(c = json_object_get_array(json_object(node), "ids"))) {
 		return FALSE;
 	}
 
-	for (i = 0; i < c->u.array.length; i++) {
-		if (c->u.array.values[i]->type != json_integer) {
-			continue;
-		}
+	for (i = 0; i < json_array_get_count(c); i++) {
+		jint id = json_array_get_integer(c, i);
 
 		txl->list = g_slist_prepend(txl->list,
-		                            g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer));
-	}
-
-	c = json_o_get(node, "next_cursor");
-	if (c && c->type == json_integer) {
-		txl->next_cursor = c->u.integer;
+		                            g_strdup_printf("%lld", id));
+	}
+
+	JSON_Value *next = json_object_get_value(json_object(node), "next_cursor");
+	if (next && json_type(next) == JSONInteger) {
+		txl->next_cursor = json_integer(next);
 	} else {
 		txl->next_cursor = -1;
@@ -329,5 +331,5 @@
 {
 	struct im_connection *ic;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 	struct twitter_data *td;
@@ -373,5 +375,5 @@
 {
 	struct im_connection *ic = req->data;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 	struct twitter_data *td;
@@ -418,5 +420,5 @@
 {
 	struct im_connection *ic = req->data;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 	struct twitter_data *td;
@@ -444,13 +446,11 @@
 	// Process the retweet ids
 	txl->type = TXL_ID;
-	if (parsed->type == json_array) {
+	if (json_type(parsed) == JSONArray) {
+		JSON_Array *arr = json_array(parsed);
 		unsigned int i;
-		for (i = 0; i < parsed->u.array.length; i++) {
-			json_value *c = parsed->u.array.values[i];
-			if (c->type != json_integer) {
-				continue;
-			}
+		for (i = 0; i < json_array_get_count(arr); i++) {
+			jint id = json_array_get_integer(arr, i);
 			txl->list = g_slist_prepend(txl->list,
-			                            g_strdup_printf("%"PRIu64, c->u.integer));
+			                            g_strdup_printf("%lld", id));
 		}
 	}
@@ -463,5 +463,5 @@
 }
 
-static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl);
+static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl);
 static void twitter_http_get_users_lookup(struct http_request *req);
 
@@ -504,5 +504,5 @@
 {
 	struct im_connection *ic = req->data;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 	GSList *l = NULL;
@@ -537,15 +537,15 @@
 }
 
-struct twitter_xml_user *twitter_xt_get_user(const json_value *node)
+struct twitter_xml_user *twitter_xt_get_user(const JSON_Object *node)
 {
 	struct twitter_xml_user *txu;
-	json_value *jv;
+	
+	if (!node)
+		return NULL;
 
 	txu = g_new0(struct twitter_xml_user, 1);
-	txu->name = g_strdup(json_o_str(node, "name"));
-	txu->screen_name = g_strdup(json_o_str(node, "screen_name"));
-
-	jv = json_o_get(node, "id");
-	txu->uid = jv->u.integer;
+	txu->name = g_strdup(json_object_get_string(node, "name"));
+	txu->screen_name = g_strdup(json_object_get_string(node, "screen_name"));
+	txu->uid = json_object_get_integer(node, "id");
 
 	return txu;
@@ -557,5 +557,5 @@
  *  - all <user>s from the <users> element.
  */
-static gboolean twitter_xt_get_users(json_value *node, struct twitter_xml_list *txl)
+static gboolean twitter_xt_get_users(JSON_Value *node, struct twitter_xml_list *txl)
 {
 	struct twitter_xml_user *txu;
@@ -565,12 +565,16 @@
 	txl->type = TXL_USER;
 
-	if (!node || node->type != json_array) {
+	if (json_type(node) != JSONArray) {
 		return FALSE;
 	}
-
+	
 	// The root <users> node should hold the list of users <user>
 	// Walk over the nodes children.
-	for (i = 0; i < node->u.array.length; i++) {
-		txu = twitter_xt_get_user(node->u.array.values[i]);
+	JSON_Array *arr = json_array(node);
+	for (i = 0; i < json_array_get_count(arr); i++) {
+		JSON_Object *o = json_array_get_object(arr, i);
+		if (!o)
+			continue;
+		txu = twitter_xt_get_user(o);
 		if (txu) {
 			txl->list = g_slist_prepend(txl->list, txu);
@@ -587,5 +591,5 @@
 #endif
 
-static void expand_entities(char **text, const json_value *node, const json_value *extended_node);
+static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node);
 
 /**
@@ -597,12 +601,12 @@
  *  - the user in a twitter_xml_user struct.
  */
-static struct twitter_xml_status *twitter_xt_get_status(const json_value *node)
+static struct twitter_xml_status *twitter_xt_get_status(const JSON_Object *node)
 {
 	struct twitter_xml_status *txs = {0};
-	const json_value *rt = NULL;
-	const json_value *text_value = NULL;
-	const json_value *extended_node = NULL;
-
-	if (node->type != json_object) {
+	const JSON_Object *rt = NULL;
+	const JSON_Value *text_value = NULL;
+	const JSON_Object *extended_node = NULL;
+
+	if (!node) {
 		return FALSE;
 	}
@@ -610,14 +614,14 @@
 
 	JSON_O_FOREACH(node, k, v) {
-		if (strcmp("text", k) == 0 && v->type == json_string && text_value == NULL) {
+		if (strcmp("text", k) == 0 && json_type(v) == JSONString && text_value == NULL) {
 			text_value = v;
-		} else if (strcmp("full_text", k) == 0 && v->type == json_string) {
+		} else if (strcmp("full_text", k) == 0 && json_type(v) == JSONString) {
 			text_value = v;
-		} else if (strcmp("extended_tweet", k) == 0 && v->type == json_object) {
-			text_value = json_o_get(v, "full_text");
-			extended_node = v;
-		} else if (strcmp("retweeted_status", k) == 0 && v->type == json_object) {
-			rt = v;
-		} else if (strcmp("created_at", k) == 0 && v->type == json_string) {
+		} else if (strcmp("extended_tweet", k) == 0 && json_type(v) == JSONObject) {
+			text_value = json_object_get_value(json_object(v), "full_text");
+			extended_node = json_object(v);
+		} else if (strcmp("retweeted_status", k) == 0 && (rt = json_object(v))) {
+			// Handling below.
+		} else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
 			struct tm parsed;
 
@@ -625,13 +629,13 @@
 			   this field. :-( Also assumes the timezone used
 			   is UTC since C time handling functions suck. */
-			if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
+			if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
 				txs->created_at = mktime_utc(&parsed);
 			}
-		} else if (strcmp("user", k) == 0 && v->type == json_object) {
-			txs->user = twitter_xt_get_user(v);
-		} else if (strcmp("id", k) == 0 && v->type == json_integer) {
-			txs->rt_id = txs->id = v->u.integer;
-		} else if (strcmp("in_reply_to_status_id", k) == 0 && v->type == json_integer) {
-			txs->reply_to = v->u.integer;
+		} else if (strcmp("user", k) == 0 && json_type(v) == JSONObject) {
+			txs->user = twitter_xt_get_user(json_object(v));
+		} else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
+			txs->rt_id = txs->id = json_integer(v);
+		} else if (strcmp("in_reply_to_status_id", k) == 0 && json_type(v) == JSONInteger) {
+			txs->reply_to = json_integer(v);
 		}
 	}
@@ -646,6 +650,6 @@
 			txs_free(rtxs);
 		}
-	} else if (text_value && text_value->type == json_string) {
-		txs->text = g_memdup(text_value->u.string.ptr, text_value->u.string.length + 1);
+	} else if (text_value && json_type(text_value) == JSONString) {
+		txs->text = g_strdup(json_string(text_value));
 		strip_html(txs->text);
 		expand_entities(&txs->text, node, extended_node);
@@ -663,9 +667,9 @@
  * Function to fill a twitter_xml_status struct (DM variant).
  */
-static struct twitter_xml_status *twitter_xt_get_dm(const json_value *node)
+static struct twitter_xml_status *twitter_xt_get_dm(const JSON_Object *node)
 {
 	struct twitter_xml_status *txs;
 
-	if (node->type != json_object) {
+	if (!node) {
 		return FALSE;
 	}
@@ -673,8 +677,7 @@
 
 	JSON_O_FOREACH(node, k, v) {
-		if (strcmp("text", k) == 0 && v->type == json_string) {
-			txs->text = g_memdup(v->u.string.ptr, v->u.string.length + 1);
+		if (strcmp("text", k) == 0 && (txs->text = g_strdup(json_string(v)))) {
 			strip_html(txs->text);
-		} else if (strcmp("created_at", k) == 0 && v->type == json_string) {
+		} else if (strcmp("created_at", k) == 0 && json_type(v) == JSONString) {
 			struct tm parsed;
 
@@ -682,11 +685,11 @@
 			   this field. :-( Also assumes the timezone used
 			   is UTC since C time handling functions suck. */
-			if (strptime(v->u.string.ptr, TWITTER_TIME_FORMAT, &parsed) != NULL) {
+			if (strptime(json_string(v), TWITTER_TIME_FORMAT, &parsed) != NULL) {
 				txs->created_at = mktime_utc(&parsed);
 			}
-		} else if (strcmp("sender", k) == 0 && v->type == json_object) {
-			txs->user = twitter_xt_get_user(v);
-		} else if (strcmp("id", k) == 0 && v->type == json_integer) {
-			txs->id = v->u.integer;
+		} else if (strcmp("sender", k) == 0 && json_type(v) == JSONObject) {
+			txs->user = twitter_xt_get_user(json_object(v));
+		} else if (strcmp("id", k) == 0 && json_type(v) == JSONInteger) {
+			txs->id = json_integer(v);
 		}
 	}
@@ -702,12 +705,12 @@
 }
 
-static void expand_entities(char **text, const json_value *node, const json_value *extended_node)
-{
-	json_value *entities, *extended_entities, *quoted;
+static void expand_entities(char **text, const JSON_Object *node, const JSON_Object *extended_node)
+{
+	JSON_Object *entities, *extended_entities, *quoted;
 	char *quote_url = NULL, *quote_text = NULL;
 
-	if (!((entities = json_o_get(node, "entities")) && entities->type == json_object))
-		return;
-	if ((quoted = json_o_get(node, "quoted_status")) && quoted->type == json_object) {
+	if (!(entities = json_object_get_object(node, "entities")))
+		return;
+	if ((quoted = json_object_get_object(node, "quoted_status"))) {
 		/* New "retweets with comments" feature. Note that this info
 		 * seems to be included in the streaming API only! Grab the
@@ -723,6 +726,6 @@
 
 	if (extended_node) {
-		extended_entities = json_o_get(extended_node, "entities");
-		if (extended_entities && extended_entities->type == json_object) {
+		extended_entities = json_object_get_object(extended_node, "entities");
+		if (extended_entities) {
 			entities = extended_entities;
 		}
@@ -732,5 +735,5 @@
 		int i;
 
-		if (v->type != json_array) {
+		if (json_type(v) != JSONArray) {
 			continue;
 		}
@@ -739,14 +742,15 @@
 		}
 
-		for (i = 0; i < v->u.array.length; i++) {
+		for (i = 0; i < json_array_get_count(json_array(v)); i++) {
 			const char *format = "%s%s <%s>%s";
-
-			if (v->u.array.values[i]->type != json_object) {
+			JSON_Object *r = json_array_get_object(json_array(v), i);
+
+			if (!r) {
 				continue;
 			}
 
-			const char *kort = json_o_str(v->u.array.values[i], "url");
-			const char *disp = json_o_str(v->u.array.values[i], "display_url");
-			const char *full = json_o_str(v->u.array.values[i], "expanded_url");
+			const char *kort = json_object_get_string(r, "url");
+			const char *disp = json_object_get_string(r, "display_url");
+			const char *full = json_object_get_string(r, "expanded_url");
 			char *pos, *new;
 
@@ -777,5 +781,5 @@
  *  - the next_cursor.
  */
-static gboolean twitter_xt_get_status_list(struct im_connection *ic, const json_value *node,
+static gboolean twitter_xt_get_status_list(struct im_connection *ic, const JSON_Value *node,
                                            struct twitter_xml_list *txl)
 {
@@ -786,5 +790,5 @@
 	txl->type = TXL_STATUS;
 
-	if (node->type != json_array) {
+	if (json_type(node) != JSONArray) {
 		return FALSE;
 	}
@@ -792,6 +796,6 @@
 	// The root <statuses> node should hold the list of statuses <status>
 	// Walk over the nodes children.
-	for (i = 0; i < node->u.array.length; i++) {
-		txs = twitter_xt_get_status(node->u.array.values[i]);
+	for (i = 0; i < json_array_get_count(json_array(node)); i++) {
+		txs = twitter_xt_get_status(json_array_get_object(json_array(node), i));
 		if (!txs) {
 			continue;
@@ -978,5 +982,5 @@
 	
 	/* Check this is not a tweet that should be muted */
-	uid_str = g_strdup_printf("%" PRIu64, status->user->uid);
+	uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, status->user->uid);
 
 	if (g_slist_find_custom(td->mutes_ids, uid_str, (GCompareFunc)strcmp)) {
@@ -1013,5 +1017,5 @@
 }
 
-static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter);
+static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter);
 
 static void twitter_http_stream(struct http_request *req)
@@ -1019,5 +1023,5 @@
 	struct im_connection *ic = req->data;
 	struct twitter_data *td;
-	json_value *parsed;
+	JSON_Value *parsed;
 	int len = 0;
 	char c, *nl;
@@ -1060,7 +1064,7 @@
 		req->reply_body[len] = '\0';
 
-		if ((parsed = json_parse(req->reply_body, req->body_size))) {
+		if ((parsed = json_parse_string(req->reply_body))) {
 			from_filter = (req == td->filter_stream);
-			twitter_stream_handle_object(ic, parsed, from_filter);
+			twitter_stream_handle_object(ic, json_object(parsed), from_filter);
 		}
 		json_value_free(parsed);
@@ -1076,12 +1080,12 @@
 }
 
-static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o);
+static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o);
 static gboolean twitter_stream_handle_status(struct im_connection *ic, struct twitter_xml_status *txs);
 
-static gboolean twitter_stream_handle_object(struct im_connection *ic, json_value *o, gboolean from_filter)
+static gboolean twitter_stream_handle_object(struct im_connection *ic, JSON_Object *o, gboolean from_filter)
 {
 	struct twitter_data *td = ic->proto_data;
 	struct twitter_xml_status *txs;
-	json_value *c;
+	JSON_Object *c;
 
 	if ((txs = twitter_xt_get_status(o))) {
@@ -1090,5 +1094,5 @@
 		txs_free(txs);
 		return ret;
-	} else if ((c = json_o_get(o, "direct_message")) &&
+	} else if ((c = json_object_get_object(o, "direct_message")) &&
 	           (txs = twitter_xt_get_dm(c))) {
 		if (g_strcasecmp(txs->user->screen_name, td->user) != 0) {
@@ -1098,12 +1102,12 @@
 		txs_free(txs);
 		return TRUE;
-	} else if ((c = json_o_get(o, "event")) && c->type == json_string) {
+	} else if (json_object_get_string(o, "event")) {
 		twitter_stream_handle_event(ic, o);
 		return TRUE;
-	} else if ((c = json_o_get(o, "disconnect")) && c->type == json_object) {
+	} else if ((c = json_object_get_object(o, "disconnect"))) {
 		/* HACK: Because we're inside an event handler, we can't just
 		   disconnect here. Instead, just change the HTTP status string
 		   into a Twitter status string. */
-		char *reason = json_o_strdup(c, "reason");
+		char *reason = g_strdup(json_object_get_string(c, "reason"));
 		if (reason) {
 			g_free(td->stream->status_string);
@@ -1144,15 +1148,14 @@
 }
 
-static gboolean twitter_stream_handle_event(struct im_connection *ic, json_value *o)
+static gboolean twitter_stream_handle_event(struct im_connection *ic, JSON_Object *o)
 {
 	struct twitter_data *td = ic->proto_data;
-	json_value *source = json_o_get(o, "source");
-	json_value *target = json_o_get(o, "target");
-	const char *type = json_o_str(o, "event");
+	JSON_Object *source = json_object_get_object(o, "source");
+	JSON_Object *target = json_object_get_object(o, "target");
+	const char *type = json_object_get_string(o, "event");
 	struct twitter_xml_user *us = NULL;
 	struct twitter_xml_user *ut = NULL;
 
-	if (!type || !source || source->type != json_object
-	    || !target || target->type != json_object) {
+	if (!type || !source || !target) {
 		return FALSE;
 	}
@@ -1168,5 +1171,5 @@
 		char *uid_str;
 		ut = twitter_xt_get_user(target);
-		uid_str = g_strdup_printf("%" PRIu64, ut->uid);
+		uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid);
 		if (!(found = g_slist_find_custom(td->mutes_ids, uid_str,
 		                                  (GCompareFunc)strcmp))) {
@@ -1175,5 +1178,5 @@
 		twitter_log(ic, "Muted user %s", ut->screen_name);
 		if (getenv("BITLBEE_DEBUG")) {
-			fprintf(stderr, "New mute: %s %"PRIu64"\n",
+			fprintf(stderr, "New mute: %s %"G_GUINT64_FORMAT"\n",
 			        ut->screen_name, ut->uid);
 		}
@@ -1182,5 +1185,5 @@
 		char *uid_str;
 		ut = twitter_xt_get_user(target);
-		uid_str = g_strdup_printf("%" PRIu64, ut->uid);
+		uid_str = g_strdup_printf("%" G_GUINT64_FORMAT, ut->uid);
 		if ((found = g_slist_find_custom(td->mutes_ids, uid_str,
 		                                (GCompareFunc)strcmp))) {
@@ -1192,5 +1195,5 @@
 		twitter_log(ic, "Unmuted user %s", ut->screen_name);
 		if (getenv("BITLBEE_DEBUG")) {
-			fprintf(stderr, "New unmute: %s %"PRIu64"\n",
+			fprintf(stderr, "New unmute: %s %"G_GUINT64_FORMAT"\n",
 			        ut->screen_name, ut->uid);
 		}
@@ -1283,7 +1286,5 @@
 	struct twitter_filter *tf;
 	GList *users = NULL;
-	json_value *parsed;
-	json_value *id;
-	const char *name;
+	JSON_Value *parsed;
 	GString *fstr;
 	GSList *l;
@@ -1310,13 +1311,14 @@
 	}
 
-	if (parsed->type != json_array) {
+	if (json_type(parsed) != JSONArray) {
 		goto finish;
 	}
 
-	for (i = 0; i < parsed->u.array.length; i++) {
-		id = json_o_get(parsed->u.array.values[i], "id");
-		name = json_o_str(parsed->u.array.values[i], "screen_name");
-
-		if (!name || !id || id->type != json_integer) {
+	for (i = 0; i < json_array_get_count(json_array(parsed)); i++) {
+		JSON_Object *o = json_array_get_object(json_array(parsed), i);
+		jint id = json_object_get_integer(o, "id");
+		const char *name = json_object_get_string(o, "screen_name");
+
+		if (!name || !id) {
 			continue;
 		}
@@ -1326,5 +1328,5 @@
 
 			if (g_strcasecmp(tf->text, name) == 0) {
-				tf->uid = id->u.integer;
+				tf->uid = id;
 				users = g_list_delete_link(users, u);
 				break;
@@ -1571,5 +1573,5 @@
 	struct im_connection *ic = req->data;
 	struct twitter_data *td;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 
@@ -1611,5 +1613,5 @@
 	struct im_connection *ic = req->data;
 	struct twitter_data *td;
-	json_value *parsed;
+	JSON_Value *parsed;
 	struct twitter_xml_list *txl;
 
@@ -1652,5 +1654,6 @@
 	struct im_connection *ic = req->data;
 	struct twitter_data *td;
-	json_value *parsed, *id;
+	JSON_Value *parsed;
+	jint id;
 
 	// Check if the connection is still active.
@@ -1666,6 +1669,6 @@
 	}
 
-	if ((id = json_o_get(parsed, "id")) && id->type == json_integer) {
-		td->last_status_id = id->u.integer;
+	if ((id = json_object_get_integer(json_object(parsed), "id"))) {
+		td->last_status_id = id;
 	}
 
@@ -1788,5 +1791,6 @@
 {
 	struct im_connection *ic = req->data;
-	json_value *parsed, *id;
+	JSON_Value *parsed;
+	uint64_t id;
 	const char *name;
 
@@ -1800,14 +1804,9 @@
 	}
 
-	/* for the parson branch:
 	name = json_object_dotget_string(json_object(parsed), "user.screen_name");
 	id = json_object_get_integer(json_object(parsed), "id");
-	*/
-
-	name = json_o_str(json_o_get(parsed, "user"), "screen_name");
-	id = json_o_get(parsed, "id");
-
-	if (name && id && id->type == json_integer) {
-		twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer);
+
+	if (name && id) {
+		twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id);
 	} else {
 		twitter_log(ic, "Error: could not fetch tweet url.");
