private static void SerializeEnumerable(JsonWriter writer, object obj, Type valueType, ISurrogateContext context)
        {
            var isArray = valueType.IsArray;

            if (isArray)
            {
                var length = (obj as Array).Length;
                writer.WritePropertyName("__isArray");
                writer.WriteValue(isArray);
                writer.WritePropertyName("__arrayLength");
                writer.WriteValue(length);
                writer.WritePropertyName("__elementType");
                string elementTypeName = SurrogatesDirectory.TypeToContractedString(valueType.GetElementType());
                writer.WriteValue(elementTypeName);
            }
            writer.WritePropertyName("__arr");

            var array = obj as IEnumerable;

            writer.WriteStartArray();
            foreach (object item in array)
            {
                var prop = item.GetType();
                WriteValueAux(writer, item, prop, context);
            }

            writer.WriteEndArray();
        }
        /// <summary>
        /// Writes the given object and returns the JSON string
        /// </summary>
        public static void WriteObject(JsonWriter writer, object value, ISurrogateContext context)
        {
            writer.WriteStartObject();
            Type valueType = value.GetType();

            writer.WritePropertyName("__type");
            string assemblyQualifiedName = SurrogatesDirectory.TypeToContractedString(valueType);

            writer.WriteValue(assemblyQualifiedName);
            if (value is System.Collections.IDictionary)
            {
                SerializeDictionary(writer, value, context);
            }
            else if (value is System.Collections.IEnumerable)
            {
                SerializeEnumerable(writer, value, valueType, context);
            }
            else
            {
                var fldArr = GetFieldInfosIncludingBaseClasses(valueType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                for (var i = 0; i < fldArr.Count; i++)
                {
                    var propEx       = fldArr[i];
                    var propValue    = propEx.GetValue(value);
                    var currentField = fldArr[i];
                    if (typeof(IStateObject).IsAssignableFrom(currentField.FieldType))
                    {
                        writer.WritePropertyName(propEx.Name);
                        writer.WriteValue(((IStateObject)propValue).UniqueID);
                    }
                    else if (currentField.FieldType.IsSerializable && typeof(MulticastDelegate).IsAssignableFrom(currentField.FieldType))
                    {
                        //Skip do no support delegate fields
                    }
                    else if (SurrogatesDirectory.IsSurrogateRegistered(currentField.FieldType))
                    {
                        if (propValue != null)
                        {
                            var surr = context.GetStateObjectSurrogate(propValue, generateIfNotFound: false);
                            if (surr == null)
                            {
                                throw new InvalidOperationException();
                            }

                            writer.WritePropertyName(propEx.Name);
                            writer.WriteValue(((IStateObject)surr).UniqueID);
                        }
                        else
                        {
                            writer.WritePropertyName(propEx.Name);
                            writer.WriteValue(String.Empty);
                        }
                    }
                    else
                    {
                        //Lets check if that value is not a dependency.
                        //if (dependencies != null && IsObjectInDependencies(dependencies, propValue))
                        //    continue;
                        writer.WritePropertyName(propEx.Name);
                        WriteValueAux(writer, propValue, propEx.FieldType, context);
                    }
                }
            }
            writer.WriteEndObject();
        }