private void SerializeDictionaryGeneric <TValue>(ISerializerNode node,
                                                         Writer writer,
                                                         DictionaryTypeSpec dictType)
        {
            var jsonWriter        = writer.JsonWriter;
            var dict              = (IDictionary <string, TValue>)node.Value;
            var expectedValueType = dictType.ValueType;

            jsonWriter.WriteStartObject();
            var dictDelta = dict as IDictionaryDelta <string, TValue>;
            var serializedKeyValuePairs = dictDelta != null ? dictDelta.ModifiedItems : dict;

            if (dictDelta != null && dictDelta.RemovedKeys.Any())
            {
                foreach (var removed in dictDelta.RemovedKeys)
                {
                    jsonWriter.WritePropertyName("-" + EscapePropertyName(removed));
                    jsonWriter.WriteStartObject();
                    jsonWriter.WriteEndObject();
                }
            }

            foreach (var kvp in serializedKeyValuePairs)
            {
                // TODO: Support other key types than string
                jsonWriter.WritePropertyName(EscapePropertyName(kvp.Key));
                var itemNode = new ItemValueSerializerNode(kvp.Value, expectedValueType, node.ExpandPath, node.Context, node);
                SerializeThroughContext(itemNode, writer);
            }

            jsonWriter.WriteEndObject();
        }
        private void SerializeCollection(ISerializerNode node, Writer writer)
        {
            var jsonWriter = writer.JsonWriter;

            if (node.SerializeAsReference)
            {
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("_ref");
                jsonWriter.WriteValue(node.Uri);
                jsonWriter.WriteEndObject();
            }
            else
            {
                jsonWriter.WriteStartArray();
                TypeSpec baseElementType;
                if (node.ExpectedBaseType != null && node.ExpectedBaseType.IsCollection)
                {
                    baseElementType = node.ExpectedBaseType.ElementType;
                }
                else
                {
                    baseElementType = node.Context.GetClassMapping(typeof(object));
                }

                var delta = node.Value as ICollectionDelta;
                if (delta != null)
                {
                    foreach (var item in delta.AddedItems.Concat(delta.ModifiedItems))
                    {
                        var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node);
                        SerializeThroughContext(itemNode, writer);
                    }
                    foreach (var item in delta.RemovedItems)
                    {
                        var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node, true);
                        SerializeThroughContext(itemNode, writer);
                    }
                }
                else
                {
                    foreach (var item in (IEnumerable)node.Value)
                    {
                        var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node);
                        SerializeThroughContext(itemNode, writer);
                    }
                }
                jsonWriter.WriteEndArray();
            }
        }