/// <summary>
 /// Overrides reflection result with <see cref="TypeOverride"/> for the specific type and optionally purge existing overrides.
 /// </summary>
 /// <param name="type">The type to be overridden.</param>
 /// <param name="overrideInfo">The override info of the type.</param>
 /// <param name="purgeExisting">If this value is true, the reflection engine will reflect the type again and apply the <paramref name="overrideInfo"/>, otherwise, <paramref name="overrideInfo"/> is merged into the existing reflection cache.</param>
 /// <remarks>
 /// <para>At this moment, the override only affects the registered type.</para>
 /// <para>If a class has its subclasses, the override will not be applied to its subclasses.</para>
 /// </remarks>
 /// <exception cref="ArgumentNullException">The parameter <paramref name="type"/> or <paramref name="overrideInfo"/> is null.</exception>
 /// <exception cref="MissingMemberException">No member is found for a <see cref="MemberOverride"/> in <paramref name="overrideInfo"/>.</exception>
 public void Override(Type type, TypeOverride overrideInfo, bool purgeExisting)
 {
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     if (overrideInfo == null)
     {
         throw new ArgumentNullException("overrideInfo");
     }
     lock (_syncRoot) {
         var s = GetSerializationInfo(type);
         if (purgeExisting)
         {
             LoadSerializationInfo(s);
         }
         OverrideSerializationInfo(s, overrideInfo);
         if (overrideInfo._MemberOverrides == null || overrideInfo._MemberOverrides.Count == 0)
         {
             return;
         }
         // add properties ignored by _controller in GetProperties method
         foreach (var ov in overrideInfo._MemberOverrides)
         {
             //if (ov.Deserializable != true) {
             //	continue;
             //}
             var p = s.FindProperties(ov.MemberName);
             if (p.Count == 0)
             {
                 var m = s.Reflection.FindMemberCache(ov.MemberName);
                 if (m == null)
                 {
                     throw new MissingMemberException(s.Reflection.TypeName, ov.MemberName);
                 }
                 var pi = new JsonMemberSetter(s, m, this);
                 // TODO: load serialization control settings
                 var ds = LoadMemberDeserializationSettings(pi, _controller);
                 if (ds != null)
                 {
                     foreach (var item in ds)
                     {
                         AddSetter(s.Setters, item.Key, item.Value);
                     }
                 }
             }
         }
         foreach (var ov in overrideInfo._MemberOverrides)
         {
             var g = s.FindGetters(ov.MemberName);
             if (g == null)
             {
                 throw new MissingMemberException(type.FullName, ov.MemberName);
             }
             OverrideGetter(g, ov);
             OverrideSetter(s.Setters, ov, g);
         }
     }
 }
 private void OverrideSerializationInfo(SerializationInfo info, TypeOverride overrideInfo)
 {
     if (overrideInfo.OverrideAlias)
     {
         var a = overrideInfo.Alias;
         if (String.IsNullOrEmpty(a))
         {
             _typeAliases.Remove(info.Reflection.Type);
             if (info.Alias != null)
             {
                 _reverseTypeAliases.Remove(info.Alias);
             }
         }
         else
         {
             Type t;
             if (_reverseTypeAliases.TryGetValue(a, out t))
             {
                 if (t.Equals(info.Reflection.Type) == false)
                 {
                     throw new JsonSerializationException("Type alias (" + a + ") has been used by type " + t.AssemblyQualifiedName);
                 }
             }
             else
             {
                 if (info.Alias != null)
                 {
                     _reverseTypeAliases.Remove(info.Alias);
                 }
                 info.Alias = overrideInfo.Alias;
                 _typeAliases[info.Reflection.Type] = info.Alias;
                 _reverseTypeAliases[a]             = info.Reflection.Type;
             }
         }
     }
     if (overrideInfo.OverrideInterceptor)
     {
         info.Interceptor = overrideInfo.Interceptor;
     }
     if (overrideInfo.OverrideConverter)
     {
         info.Converter = overrideInfo.Converter;
     }
     if (overrideInfo.OverrideContainerName)
     {
         info.CollectionName    = overrideInfo.CollectionContainer;
         info.DeserializeMethod = overrideInfo.CollectionContainer == null
                                 ? JsonDeserializer.GetReadJsonMethod(info.Reflection.Type)
                                 : new CompoundDeserializer(info.CollectionName, info.Reflection.DeserializeMethod).Deserialize;
     }
     if (overrideInfo.Deserializable.HasValue)
     {
         info.AlwaysDeserializable = overrideInfo.Deserializable == true;
     }
 }
 /// <summary>
 /// Overrides reflection result with <see cref="TypeOverride"/> for the <typeparamref name="T"/> type.
 /// </summary>
 /// <typeparam name="T">The type to be overridden.</typeparam>
 /// <param name="overrideInfo">The override info of the type.</param>
 /// <param name="purgeExisting">If this value is true, the reflection engine will reflect the type again and apply the <paramref name="overrideInfo"/>, otherwise, <paramref name="overrideInfo"/> is merged into the existing reflection cache.</param>
 /// <seealso cref="Override(Type,TypeOverride,bool)"/>
 public void Override <T>(TypeOverride overrideInfo, bool purgeExisting)
 {
     Override(typeof(T), overrideInfo, purgeExisting);
 }
 /// <summary>
 /// Overrides reflection result with <see cref="TypeOverride"/> for the <typeparamref name="T"/> type. If the type is already overridden, either automatically or manually, the <paramref name="overrideInfo"/> will merged into the existing reflected info.
 /// </summary>
 /// <typeparam name="T">The type to be overridden.</typeparam>
 /// <param name="overrideInfo">The override info of the type.</param>
 /// <seealso cref="Override(Type,TypeOverride,bool)"/>
 public void Override <T>(TypeOverride overrideInfo)
 {
     Override(typeof(T), overrideInfo, false);
 }