public static FB_User _from_thread_fetch(JToken data)
        {
            var c_info                 = FB_User._parse_customization_info(data);
            var participants           = data.get("all_participants")?.get("nodes")?.Select(node => node.get("messaging_actor"));
            var user                   = participants.Where((p) => p.get("id")?.Value <string>() == data.get("thread_key")?.get("other_user_id")?.Value <string>())?.FirstOrDefault();
            var last_message_timestamp = data.get("last_message")?.get("nodes")?.FirstOrDefault()?.get("timestamp_precise")?.Value <string>();

            var name       = user.get("name")?.Value <string>();
            var first_name = user.get("first_name")?.Value <string>() ?? user.get("short_name")?.Value <string>();
            var last_name  = first_name != null?name?.Replace(first_name, "")?.Trim() : null;

            var gender = GENDER.graphql_GENDERS["UNKNOWN"];

            if (data.get("gender")?.Type == JTokenType.Integer)
            {
                gender = GENDER.standard_GENDERS[data.get("gender")?.Value <int>() ?? 0];
            }
            else
            {
                int gender_int = 0;
                if (int.TryParse(data.get("gender")?.Value <string>(), out gender_int))
                {
                    gender = GENDER.standard_GENDERS[gender_int];
                }
                else
                {
                    gender = GENDER.graphql_GENDERS[data.get("gender")?.Value <string>() ?? "UNKNOWN"];
                }
            };

            if (user.get("big_image_src") == null)
            {
                user["big_image_src"] = new JObject(new JProperty("uri", ""));
            }

            var plan = data.get("event_reminders")?.get("nodes")?.FirstOrDefault() != null?FB_Plan._from_graphql(data.get("event_reminders")?.get("nodes")?.FirstOrDefault()) : null;

            return(new FB_User(
                       uid: user.get("id")?.Value <string>(),
                       url: user.get("url")?.Value <string>(),
                       name: name,
                       first_name: first_name,
                       last_name: last_name,
                       is_friend: user.get("is_viewer_friend")?.Value <bool>() ?? false,
                       gender: gender,
                       affinity: user.get("viewer_affinity")?.Value <float>() ?? 0,
                       nickname: (string)c_info.GetValueOrDefault("nickname"),
                       color: (string)c_info.GetValueOrDefault("color"),
                       emoji: (JToken)c_info.GetValueOrDefault("emoji"),
                       own_nickname: (string)c_info.GetValueOrDefault("own_nickname"),
                       photo: user.get("big_image_src")?.get("uri")?.Value <string>(),
                       message_count: data.get("messages_count")?.Value <int>() ?? 0,
                       last_message_timestamp: last_message_timestamp,
                       plan: plan));
        }
        public static FB_User _from_graphql(JToken data)
        {
            if (data.get("profile_picture") == null)
            {
                data["profile_picture"] = new JObject(new JProperty("uri", ""));
            }
            var c_info = FB_User._parse_customization_info(data);
            var plan   = data.get("event_reminders")?.get("nodes")?.FirstOrDefault() != null?FB_Plan._from_graphql(data.get("event_reminders")?.get("nodes")?.FirstOrDefault()) : null;

            var name       = data.get("name")?.Value <string>();
            var first_name = data.get("first_name")?.Value <string>() ?? data.get("short_name")?.Value <string>();
            var last_name  = first_name != null?name?.Replace(first_name, "")?.Trim() : null;

            var gender = GENDER.graphql_GENDERS["UNKNOWN"];

            if (data.get("gender")?.Type == JTokenType.Integer)
            {
                gender = GENDER.standard_GENDERS[data.get("gender")?.Value <int>() ?? 0];
            }
            else
            {
                int gender_int = 0;
                if (int.TryParse(data.get("gender")?.Value <string>(), out gender_int))
                {
                    gender = GENDER.standard_GENDERS[gender_int];
                }
                else
                {
                    gender = GENDER.graphql_GENDERS[data.get("gender")?.Value <string>() ?? "UNKNOWN"];
                }
            };

            return(new FB_User(
                       uid: data.get("id")?.Value <string>(),
                       url: data.get("url")?.Value <string>(),
                       name: name,
                       first_name: first_name,
                       last_name: last_name,
                       is_friend: data.get("is_viewer_friend")?.Value <bool>() ?? false,
                       gender: gender,
                       affinity: data.get("viewer_affinity")?.Value <float>() ?? 0,
                       nickname: (string)c_info.GetValueOrDefault("nickname"),
                       color: (string)c_info.GetValueOrDefault("color"),
                       emoji: (JToken)c_info.GetValueOrDefault("emoji"),
                       own_nickname: (string)c_info.GetValueOrDefault("own_nickname"),
                       photo: data.get("profile_picture")?.get("uri")?.Value <string>(),
                       message_count: data.get("messages_count")?.Value <int>() ?? 0,
                       plan: plan));
        }