public void GenerateLoad(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type targetType)
{
var localCount = ilGenerator.DeclareLocal(typeof(int));
var targetIDictionary = targetType.GetInterface("IDictionary`2") ?? targetType;
var targetTypeArguments = targetIDictionary.GetGenericArguments();
var keyType = _typeSerializers.LoadAsType(_keyDescriptor, targetTypeArguments[0]);
var valueType = _typeSerializers.LoadAsType(_valueDescriptor, targetTypeArguments[1]);
var dictionaryType = typeof(DictionaryWithDescriptor<,>).MakeGenericType(keyType, valueType);
if (!targetType.IsAssignableFrom(dictionaryType)) throw new InvalidOperationException();
var localDict = ilGenerator.DeclareLocal(dictionaryType);
var loadFinished = ilGenerator.DefineLabel();
var next = ilGenerator.DefineLabel();
ilGenerator
.Do(pushReader)
.Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
.ConvI4()
.Dup()
.LdcI4(1)
.Sub()
.Stloc(localCount)
.Brfalse(loadFinished)
.Ldloc(localCount)
.Do(pushDescriptor)
.Newobj(dictionaryType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
.Stloc(localDict)
.Mark(next)
.Ldloc(localCount)
.Brfalse(loadFinished)
.Ldloc(localCount)
.LdcI4(1)
.Sub()
.Stloc(localCount)
.Ldloc(localDict);
_keyDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), keyType, _convertorGenerator);
_valueDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(1).Callvirt(() => default(ITypeDescriptor).NestedType(0)), valueType, _convertorGenerator);
ilGenerator
.Callvirt(dictionaryType.GetMethod("Add"))
.Br(next)
.Mark(loadFinished)
.Ldloc(localDict)
.Castclass(targetType);
}