static gboolean
parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error)
{
	gboolean success;

	if (g_strcmp0 (json_reader_get_member_name (reader), "role") == 0) {
		gchar *role = NULL;  /* owned */

		g_assert (gdata_parser_string_from_json_member (reader, "role",
		                                                P_REQUIRED |
		                                                P_NON_EMPTY,
		                                                &role, &success,
		                                                error));

		if (!success) {
			return FALSE;
		}

		gdata_access_rule_set_role (GDATA_ACCESS_RULE (parsable),
		                            role_v3_to_v2 (role));
		g_free (role);

		return TRUE;
	} else if (g_strcmp0 (json_reader_get_member_name (reader),
	                                                   "scope") == 0) {
		const gchar *scope_type;
		const gchar *scope_value;

		/* Check this is an object. */
		if (!json_reader_is_object (reader)) {
			return gdata_parser_error_required_json_content_missing (reader,
			                                                         error);
		}

		json_reader_read_member (reader, "type");
		scope_type = json_reader_get_string_value (reader);
		json_reader_end_member (reader);

		json_reader_read_member (reader, "value");
		scope_value = json_reader_get_string_value (reader);
		json_reader_end_member (reader);

		/* Scope type is required. */
		if (scope_type == NULL) {
			return gdata_parser_error_required_json_content_missing (reader,
			                                                         error);
		}

		gdata_access_rule_set_scope (GDATA_ACCESS_RULE (parsable),
		                             scope_type_v3_to_v2 (scope_type),
		                             scope_value);

		return TRUE;
	}

	return GDATA_PARSABLE_CLASS (gdata_calendar_access_rule_parent_class)->parse_json (parsable, reader, user_data, error);
}
static gboolean
parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error)
{
	GDataDocumentsAccessRulePrivate *priv;
	gboolean success;
	gchar *key = NULL;
	gchar *role = NULL;
	gchar *scope_type = NULL;

	priv = gdata_documents_access_rule_get_instance_private (GDATA_DOCUMENTS_ACCESS_RULE (parsable));

	/* JSON format: https://developers.google.com/drive/v2/reference/permissions */

	if (gdata_parser_string_from_json_member (reader, "emailAddress", P_REQUIRED | P_NON_EMPTY, &(priv->email), &success, error) == TRUE ||
	    gdata_parser_string_from_json_member (reader, "domain", P_REQUIRED | P_NON_EMPTY, &(priv->domain), &success, error) == TRUE) {
		return success;
	} else if (gdata_parser_string_from_json_member (reader, "authKey", P_REQUIRED | P_NON_EMPTY, &key, &success, error) == TRUE) {
		if (success && key != NULL && key[0] != '\0')
			_gdata_access_rule_set_key (GDATA_ACCESS_RULE (parsable), key);

		g_free (key);
		return success;
	} else if (gdata_parser_string_from_json_member (reader, "role", P_REQUIRED | P_NON_EMPTY, &role, &success, error) == TRUE) {
		if (success && role != NULL && role[0] != '\0')
			gdata_access_rule_set_role (GDATA_ACCESS_RULE (parsable), role);

		g_free (role);
		return success;
	} else if (gdata_parser_string_from_json_member (reader, "type", P_REQUIRED | P_NON_EMPTY, &scope_type, &success, error) == TRUE) {
		if (g_strcmp0 (scope_type, "anyone") == 0) {
			priv->scope_type = g_strdup (GDATA_ACCESS_SCOPE_DEFAULT);
		} else {
			priv->scope_type = scope_type;
			scope_type = NULL;
		}

		g_free (scope_type);
		return success;
	}

	return GDATA_PARSABLE_CLASS (gdata_documents_access_rule_parent_class)->parse_json (parsable, reader, user_data, error);
}