public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var enumerators = new List <ElementEnum>();

            // When ReadJson is called, reader's token type is StartObject.
            reader.Read(); // Advance to property name.

            while (reader.TokenType != JsonToken.EndObject)
            {
                string name = (string)reader.Value;
                reader.Read(); // Advance to the next object.

                ElementEnum newEnum = new ElementEnum();
                newEnum.Name = name;

                // Direct
                if (reader.TokenType == JsonToken.StartArray)
                {
                    newEnum.Members = GetEnumMembers(newEnum, JToken.Load(reader).ToArray());
                }
                // With additional properties
                else if (reader.TokenType == JsonToken.StartObject)
                {
                    // Get the enum object.
                    var enumObject = JObject.Load(reader);

                    // 'hidden' property
                    if (enumObject.TryGetValue("hidden", out JToken hiddenValue))
                    {
                        newEnum.Hidden = hiddenValue.ToObject <bool>();
                    }

                    // Members
                    newEnum.Members = GetEnumMembers(newEnum, enumObject.GetValue("members").ToArray());
                }

                // Advance past EndObject or EndArray
                reader.Read();

                enumerators.Add(newEnum);
            }

            return(enumerators.ToArray());
        }
 private ElementEnumMember[] GetEnumMembers(ElementEnum newEnum, JToken[] members) => members.Select(v => {
 public bool TryGetEnum(string name, out ElementEnum enumerator)
 {
     enumerator = Enumerators.FirstOrDefault(e => e.Name == name);
     return(enumerator != null);
 }