bool DeobfuscateFields()
        {
            foreach (var info in fieldWrites.Values)
            {
                info.Clear();
            }

            foreach (var method in allMethods)
            {
                if (method.Body == null)
                {
                    continue;
                }
                var instructions = method.Body.Instructions;
                for (int i = 0; i < instructions.Count; i++)
                {
                    var                 instr     = instructions[i];
                    TypeSig             fieldType = null;
                    TypeInfo <FieldDef> info      = null;
                    IField              field;
                    switch (instr.OpCode.Code)
                    {
                    case Code.Stfld:
                    case Code.Stsfld:
                        field = instr.Operand as IField;
                        if (field == null)
                        {
                            continue;
                        }
                        if (!fieldWrites.TryGetValue(field, out info))
                        {
                            continue;
                        }
                        bool wasNewobj;
                        fieldType = GetLoadedType(info.arg.DeclaringType, method, instructions, i, out wasNewobj);
                        if (fieldType == null)
                        {
                            continue;
                        }
                        info.Add(fieldType, wasNewobj);
                        break;

                    case Code.Call:
                    case Code.Calli:
                    case Code.Callvirt:
                    case Code.Newobj:
                        var pushedArgs   = MethodStack.GetPushedArgInstructions(instructions, i);
                        var calledMethod = instr.Operand as IMethod;
                        if (calledMethod == null)
                        {
                            continue;
                        }
                        var calledMethodDefOrRef = calledMethod as IMethodDefOrRef;
                        var calledMethodSpec     = calledMethod as MethodSpec;
                        if (calledMethodSpec != null)
                        {
                            calledMethodDefOrRef = calledMethodSpec.Method;
                        }
                        if (calledMethodDefOrRef == null)
                        {
                            continue;
                        }

                        IList <TypeSig> calledMethodArgs = DotNetUtils.GetArgs(calledMethodDefOrRef);
                        calledMethodArgs = DotNetUtils.ReplaceGenericParameters(calledMethodDefOrRef.DeclaringType.TryGetGenericInstSig(), calledMethodSpec, calledMethodArgs);
                        for (int j = 0; j < pushedArgs.NumValidArgs; j++)
                        {
                            var pushInstr = pushedArgs.GetEnd(j);
                            if (pushInstr.OpCode.Code != Code.Ldfld && pushInstr.OpCode.Code != Code.Ldsfld)
                            {
                                continue;
                            }

                            field = pushInstr.Operand as IField;
                            if (field == null)
                            {
                                continue;
                            }
                            if (!fieldWrites.TryGetValue(field, out info))
                            {
                                continue;
                            }
                            fieldType = calledMethodArgs[calledMethodArgs.Count - 1 - j];
                            if (!IsValidType(info.arg.DeclaringType, fieldType))
                            {
                                continue;
                            }
                            info.Add(fieldType);
                        }
                        break;

                    default:
                        continue;
                    }
                }
            }

            bool modified    = false;
            var  removeThese = new List <FieldDef>();

            foreach (var info in fieldWrites.Values)
            {
                if (info.UpdateNewType(module))
                {
                    removeThese.Add(info.arg);
                    GetUpdatedField(info.arg).newFieldType = info.newType;
                    info.arg.FieldSig.Type = info.newType;
                    modified = true;
                }
            }
            foreach (var field in removeThese)
            {
                fieldWrites.Remove(field);
            }
            return(modified);
        }