private void EmitFieldsAssignmentLoop(ILProcessor ilProcessor, VariableDefinition resultVar,
                                              VariableDefinition fieldCountVar, ParameterDefinition readerParam, TypeDefinition resolved)
        {
            var iterationVar = ilProcessor.AddVariable(_mainModule.TypeSystem.Int32);
            var fieldNameVar = ilProcessor.AddVariable(_mainModule.TypeSystem.String);

            var tempstr1       = ilProcessor.AddVariable(_mainModule.TypeSystem.String);
            var switchFieldVar = ilProcessor.AddVariable(_mainModule.TypeSystem.String);

            ilProcessor.For(0, fieldCountVar, 1).Then(() =>
            {
                ilProcessor.CallMethod(readerParam, _typeHelper.MsgPackReader.ReadString).Store(fieldNameVar);
                var switchStatement = ilProcessor.Switch(fieldNameVar);
                foreach (var field in resolved.Fields)
                {
                    switchStatement.Case(field.Name, () =>
                    {
                        if (resolved.IsValueType)
                        {
                            ilProcessor.Emit(OpCodes.Ldloca, resultVar);
                        }
                        else
                        {
                            ilProcessor.Emit(OpCodes.Ldloc, resultVar);
                        }
                        var deserializationMethod = GetTypeDeserializationMethod(field.FieldType);
                        ilProcessor.Emit(OpCodes.Ldarg, readerParam);
                        ilProcessor.Emit(OpCodes.Call, deserializationMethod);
                        ilProcessor.Emit(OpCodes.Stfld, field);
                    });
                }
            });
        }
        private void BuildDeserializeComplexClassBody(ILProcessor ilProcessor,
                                                      ParameterDefinition readerParam, TypeDefinition resolved)
        {
            var resultVar     = ilProcessor.AddVariable(resolved);
            var fieldCountVar = ilProcessor.AddVariable(_mainModule.TypeSystem.Int32);

            Instruction retInstr = Instruction.Create(OpCodes.Ret);

            if (resolved.IsValueType)
            {
                ilProcessor.Emit(OpCodes.Ldloca_S, resultVar);
                ilProcessor.Emit(OpCodes.Initobj, resolved);

                var mapTempVar = ilProcessor.AddVariable(_mainModule.TypeSystem.Boolean);
                ilProcessor.Emit(OpCodes.Ldarg, readerParam);
                ilProcessor.Emit(OpCodes.Ldloca_S, fieldCountVar);
                ilProcessor.Emit(OpCodes.Call, _typeHelper.MsgPackReader.ReadMapHeader);
                ilProcessor.Emit(OpCodes.Stloc, mapTempVar);

                EmitFieldsAssignmentLoop(ilProcessor, resultVar, fieldCountVar, readerParam, resolved);
            }
            else
            {
                var ifTempVar = ilProcessor.AddVariable(_mainModule.TypeSystem.Boolean);
                ilProcessor.CallMethod(readerParam, _typeHelper.MsgPackReader.TryReadNil).Store(ifTempVar);
                ilProcessor.If(ifTempVar).True().Then(() =>
                {
                    ilProcessor.Emit(OpCodes.Ldnull);
                    ilProcessor.Emit(OpCodes.Stloc, resultVar);
                }).Else(() =>
                {
                    var ctor = resolved.GetConstructors().FirstOrDefault(ctr => ctr.Parameters.Count == 0);
                    if (ctor == null)
                    {
                        throw new InvalidOperationException($"Type {resolved} does not have default constructor");
                    }
                    ilProcessor.Emit(OpCodes.Newobj, ctor);
                    ilProcessor.Emit(OpCodes.Stloc, resultVar);

                    var mapTempVar = ilProcessor.AddVariable(_mainModule.TypeSystem.Boolean);
                    ilProcessor.Emit(OpCodes.Ldarg, readerParam);
                    ilProcessor.Emit(OpCodes.Ldloca_S, fieldCountVar);
                    ilProcessor.Emit(OpCodes.Call, _typeHelper.MsgPackReader.ReadMapHeader);
                    ilProcessor.Emit(OpCodes.Stloc, mapTempVar);

                    //ilProcessor.CallMethod(readerParam, _typeHelper.MsgPackReader.ReadMapHeader, fieldCountVar).Store(mapTempVar);

                    EmitFieldsAssignmentLoop(ilProcessor, resultVar, fieldCountVar, readerParam, resolved);
                });
            }

            ilProcessor.Emit(OpCodes.Ldloc, resultVar);
            ilProcessor.Emit(OpCodes.Ret);
        }
        internal ForStatement(ILProcessor processor, int from, OperandBase to, int inc)
        {
            if (processor.Body.Method.Module == null)
            {
                throw new MethodNotRegisteredException(
                          $"Method {processor.Body.Method} must be added to class and registered in module");
            }
            _processor = processor;
            var iterator = processor.AddVariable(processor.Body.Method.Module.TypeSystem.Int32);

            Iterator = iterator;
            EmitIteratorInitialization(from);

            _loopStart    = Instruction.Create(OpCodes.Nop);
            ConditionCode = CreateConditionCode(to, inc);
            _processor.Emit(OpCodes.Br, _conditionStart);
            _processor.Append(_loopStart);
            _loopEnd = Instruction.Create(OpCodes.Nop);
        }