public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var filter = new SourceFilter();

            switch (reader.TokenType)
            {
            case JsonToken.Boolean:
                filter.Exclude = new[] { "*" };
                break;

            case JsonToken.String:
                filter.Include = new [] { (string)reader.Value };
                break;

            case JsonToken.StartArray:
                var include = new List <string>();
                while (reader.Read() && reader.TokenType != JsonToken.EndArray)
                {
                    include.Add((string)reader.Value);
                }
                filter.Include = include.ToArray();
                break;

            default:
                serializer.Populate(reader, filter);
                break;
            }

            return(filter);
        }
        public ISourceFilter Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
        {
            var token = reader.GetCurrentJsonToken();

            if (token == JsonToken.Null)
            {
                reader.ReadNext();
                return(null);
            }

            var filter = new SourceFilter();

            switch (token)
            {
            case JsonToken.String:
                filter.Includes = new[] { reader.ReadString() };
                break;

            case JsonToken.BeginArray:
                var include = formatterResolver.GetFormatter <string[]>()
                              .Deserialize(ref reader, formatterResolver);
                filter.Includes = include;
                break;

            default:
                var count = 0;
                while (reader.ReadIsInObject(ref count))
                {
                    var propertyName = reader.ReadPropertyNameSegmentRaw();
                    if (Fields.TryGetValue(propertyName, out var value))
                    {
                        var includeExclude = formatterResolver.GetFormatter <Fields>()
                                             .Deserialize(ref reader, formatterResolver);

                        switch (value)
                        {
                        case 0:
                            filter.Includes = includeExclude;
                            break;

                        case 1:
                            filter.Excludes = includeExclude;
                            break;
                        }
                    }
                    else
                    {
                        reader.ReadNextBlock();
                    }
                }
                break;
            }

            return(filter);
        }