public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject      = JObject.Load(reader);
            var typeKey         = jsonObject["type"] ?? jsonObject["Type"];
            var typeValue       = typeKey.Value <string>();
            var hasTypeFactory  = TypeFactories.ContainsKey(typeValue);
            var dataTypeFactory = DataDrivenTypeFactory.ContainsKey(typeValue);

            IDirective directive;

            if (hasTypeFactory)
            {
                directive = TypeFactories[typeValue]();
            }
            else if (dataTypeFactory)
            {
                directive = DataDrivenTypeFactory[typeValue](jsonObject);
            }
            else
            {
                directive = new JsonDirective(typeValue);
            }

            serializer.Populate(jsonObject.CreateReader(), directive);

            return(directive);
        }
        public void NewDirectiveSupport()
        {
            var directive = new JsonDirective("UnknownDirectiveType");

            directive.Properties.Add("testProperty", new JObject(new JProperty("value", "test")));
            var jsonOutput = JsonConvert.SerializeObject(directive);

            var outputDirective = JsonConvert.DeserializeObject <IDirective>(jsonOutput);
            var jsonInput       = Assert.IsType <JsonDirective>(outputDirective);

            Assert.Equal("UnknownDirectiveType", jsonInput.Type);
            Assert.True(jsonInput.Properties.ContainsKey("testProperty"));
            var jsonObject = Assert.IsType <JObject>(jsonInput.Properties["testProperty"]);

            Assert.Equal("test", jsonObject.Value <string>("value"));
        }