/// <summary>
        /// Populates all pair-wise combinations of defs and uses identified through static analysis
        /// </summary>
        public void PopulateDUCoverTable()
        {
            DUCoverStore dcs = DUCoverStore.GetInstance();

            SafeSet <FieldDefUseStore> allDefs = new SafeSet <FieldDefUseStore>();

            allDefs.AddRange(this.DefDic.Keys);
            allDefs.AddRange(this.DefOrUseSet);

            SafeSet <FieldDefUseStore> allUses = new SafeSet <FieldDefUseStore>();

            allUses.AddRange(this.UseDic.Keys);
            allUses.AddRange(this.DefOrUseSet);
            int numInfeasible = 0;

            //Compute pair-wise combinations
            foreach (var defEntry in allDefs)
            {
                foreach (var useEntry in allUses)
                {
                    //Ignore the trivial entries that involve just a combination of setter and getter methods
                    if (defEntry.Method.ShortName.StartsWith("set_") && useEntry.Method.ShortName.StartsWith("get_"))
                    {
                        continue;
                    }
                    if (!this.IsFeasibleDUCoverEntry(dcs, defEntry, useEntry))
                    {
                        numInfeasible++;
                        continue;
                    }

                    DUCoverStoreEntry dcse = new DUCoverStoreEntry(this.fd, defEntry.Method, defEntry.Offset,
                                                                   useEntry.Method, useEntry.Offset);

                    if (defEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Def_UnknownSideEffectMethod = defEntry.UnknownSideEffectMethod;
                        dcse.DefUnsure = true;
                    }

                    if (useEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Use_UnknownSideEffectMethod = useEntry.UnknownSideEffectMethod;
                        dcse.UseUnsure = true;
                    }

                    if (!this.duCoverageTable.ContainsKey(dcse))
                    {
                        this.duCoverageTable[dcse] = 0;
                    }
                }
            }

            //Clear all the cached entries.
            this.feasibilityDicCache.Clear();

            logger.Debug("Detected infeasible du-pairs for field " + this.fd.FullName + "(" + numInfeasible + ")");
        }
        /// <summary>
        /// Includes filtering of the methods based on desired format
        /// </summary>
        /// <returns></returns>
        public bool TryGetFilteredWriteMethods(Field field, TypeEx declaringType, FieldModificationType desiredfmt, out SafeSet <Method> writeMethods)
        {
            //Check in the predefined store before proceeding
            if (PreDefinedMethodEffects.TryGetWriteMethods(this, field, desiredfmt, out writeMethods))
            {
                SafeSet <Method> newWriteMethods = new SafeSet <Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);

                //Filter those methods whose actual types are abstract
                SafeSet <Method> returnMethods = new SafeSet <Method>();
                foreach (Method m in writeMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                foreach (Method m in newWriteMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                writeMethods.Clear();
                writeMethods.AddRange(returnMethods);
                return(true);
            }

            //Identify those method that directly modify this field
            if (!TryGetWriteMethods(field, declaringType, out writeMethods))
            {
                return(false);
            }

            //C# supports properties. In that case, the property setter can also
            //be a viable method. add property setter and its callers also
            Property property;

            if (MethodOrFieldAnalyzer.TryGetPropertyModifyingField(this, declaringType, field, out property))
            {
                if (property.IsVisible(VisibilityContext.Exported))
                {
                    writeMethods.Add(property.Setter);
                }

                var newWriteMethods = new SafeSet <Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);
                writeMethods.AddRange(newWriteMethods);
            }

            writeMethods = FilterWriteMethodsOfUpdateType(field, desiredfmt, writeMethods);
            return(true);
        }
        private void GetCallingMethods(Field field, TypeEx declaringType, SafeSet <Method> writeMethods, SafeSet <Method> newWriteMethods)
        {
            foreach (var writeM in writeMethods)
            {
                if (writeM.Definition.DeclaredVisibility != Visibility.Private || writeM.IsConstructor)
                {
                    newWriteMethods.Add(writeM);
                    continue;
                }

                //Get other calling methods within this type
                SafeSet <Method> localCM;
                if (this.TryGetCallingMethodsInType(writeM, field, declaringType, out localCM))
                {
                    newWriteMethods.AddRange(localCM);
                }
            }
        }
        /// <summary>
        /// Retrieves the write methods for a field, if exists from the predefined settings.
        /// </summary>
        public static bool TryGetWriteMethods(IPexComponent host, Field field, FieldModificationType desiredFmt, 
            out SafeSet<Method> writeMethods)
        {
            if (!isPredefinedEffectsParsed)
                ParsePredefinedEffects(host);

            PreDefinedMethodEffectsStore pdme = new PreDefinedMethodEffectsStore(field, desiredFmt);
            PreDefinedMethodEffectsStore existingPdme;
            if (effectsStore.TryGetValue(pdme, out existingPdme))
            {
                writeMethods = new SafeSet<Method>();
                writeMethods.AddRange(existingPdme.suggestedmethodList);
                return true;
            }
            else
            {
                writeMethods = null;
                return false;
            }
        }
        /// <summary>
        /// Retrieves the write methods for a field, if exists from the predefined settings.
        /// </summary>
        public static bool TryGetWriteMethods(IPexComponent host, Field field, FieldModificationType desiredFmt,
                                              out SafeSet <Method> writeMethods)
        {
            if (!isPredefinedEffectsParsed)
            {
                ParsePredefinedEffects(host);
            }

            PreDefinedMethodEffectsStore pdme = new PreDefinedMethodEffectsStore(field, desiredFmt);
            PreDefinedMethodEffectsStore existingPdme;

            if (effectsStore.TryGetValue(pdme, out existingPdme))
            {
                writeMethods = new SafeSet <Method>();
                writeMethods.AddRange(existingPdme.suggestedmethodList);
                return(true);
            }
            else
            {
                writeMethods = null;
                return(false);
            }
        }
        /// <summary>
        /// Computes method effects statically. All written fields of a method.
        /// Can be imprecise and conservative
        /// </summary>
        /// <param name="declaringType"></param>
        /// <param name="method"></param>
        /// <param name="effects"></param>
        /// <returns></returns>
        public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method,
                                                   SafeSet <Method> visitedMethods, out MethodEffects effects)
        {
            SafeDebug.AssumeNotNull(declaringType, "declaringType");
            SafeDebug.AssumeNotNull(method, "method");

            try
            {
                if (visitedMethods == null)
                {
                    visitedMethods = new SafeSet <Method>();
                }

                if (visitedMethods.Contains(method))
                {
                    effects = null;
                    return(false);
                }

                visitedMethods.Add(method);

                //Check whether this has been computed before
                var psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase;
                if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects))
                {
                    return(true);
                }

                var res                 = new SafeSet <string>();
                var directSetFields     = new SafeSet <string>();
                var directCalledMethods = new SafeSet <Method>();
                var returnFields        = new SafeSet <Field>();
                var modificationTypeDic = new SafeDictionary <string, FieldModificationType>();
                var parameters          = method.Parameters;

                MethodBodyEx body;
                if (!method.TryGetBody(out body) || !body.HasInstructions)
                {
                    effects = null;
                    return(false);
                }

                int         callDepth = 0;
                int         offset    = 0;
                Instruction instruction;
                OpCode      prevOpcode = OpCodes.Nop;

                //Stack for load instructions
                Field lastAccessedArrayField = null;
                Field lastAccessedField      = null;

                while (body.TryGetInstruction(offset, out instruction))
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (LdcOpCodes.Contains(opCode))
                    {
                        //topIsConstant = true;
                    }
                    else if (ConvOpCodes.Contains(opCode))
                    {
                        // do not change topIsConstant
                    }
                    else
                    {
                        if (opCode == OpCodes.Stfld)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field field = instruction.Field;
                            AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type);
                        }
                        else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field accessedField = instruction.Field;

                            if (accessedField.Type.Spec == TypeSpec.SzArray)
                            {
                                lastAccessedArrayField = accessedField;
                            }
                            else
                            {
                                lastAccessedField = accessedField;
                            }
                        }
                        else if (StElemOpCodes.Contains(opCode))
                        {
                            if (lastAccessedArrayField != null)
                            {
                                //Indicates that there is n array type modified
                                AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type);
                                lastAccessedArrayField = null;
                            }
                        }
                        else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                            Method methodinner = instruction.Method;
                            SafeDebug.AssumeNotNull(method, "method");

                            directCalledMethods.Add(methodinner);
                            TypeEx methodDeclaringType;

                            //are these function calls are within the parent types
                            if (methodinner.TryGetDeclaringType(out methodDeclaringType) &&
                                declaringType.IsAssignableTo(methodDeclaringType))
                            {
                                MethodEffects methodEffects;
                                if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects))
                                {
                                    res.AddRange(methodEffects.WrittenInstanceFields);
                                    foreach (var key in methodEffects.ModificationTypeDictionary.Keys)
                                    {
                                        modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key];
                                    }
                                    directSetFields.AddRange(methodEffects.DirectSetterFields);
                                    if (methodEffects.CallDepth > callDepth)
                                    {
                                        callDepth = methodEffects.CallDepth;
                                    }
                                }
                            }
                            else
                            {
                                //introducing heuristics for inter-procedural static analysis
                                if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType &&
                                    !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get") ||
                                      methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set")))
                                {
                                    AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic,
                                                            prevOpcode, lastAccessedField, lastAccessedField.Type);
                                }
                            }
                        }
                        else if (opCode == OpCodes.Ret)
                        {
                            if (instruction.Field != null)
                            {
                                returnFields.Add(instruction.Field);
                            }
                        }
                        //topIsConstant = false;
                    }

                    prevOpcode = opCode;
                    offset     = instruction.NextOffset;
                }

                effects = new MethodEffects((IFiniteSet <string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1);
                psd.MethodEffectsDic[method.GlobalIndex] = effects;
                return(true);
            }
            catch (Exception ex)
            {
                host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects",
                                               "Failed to compute method effects for method " + method.FullName + "," + ex.Message);
                effects = null;
                return(false);
            }
        }
        /// <summary>
        /// Computes method effects statically. All written fields of a method.
        /// Can be imprecise and conservative
        /// </summary>
        /// <param name="declaringType"></param>
        /// <param name="method"></param>
        /// <param name="effects"></param>
        /// <returns></returns>
        public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method,
            SafeSet<Method> visitedMethods, out MethodEffects effects)
        {
            SafeDebug.AssumeNotNull(declaringType, "declaringType");
            SafeDebug.AssumeNotNull(method, "method");

            try
            {
                if (visitedMethods == null)
                    visitedMethods = new SafeSet<Method>();

                if (visitedMethods.Contains(method))
                {
                    effects = null;
                    return false;
                }

                visitedMethods.Add(method);

                //Check whether this has been computed before
                var psd = host.GetService<IPexMeStaticDatabase>() as PexMeStaticDatabase;
                if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects))
                    return true;

                var res = new SafeSet<string>();
                var directSetFields = new SafeSet<string>();
                var directCalledMethods = new SafeSet<Method>();
                var returnFields = new SafeSet<Field>();
                var modificationTypeDic = new SafeDictionary<string, FieldModificationType>();
                var parameters = method.Parameters;

                MethodBodyEx body;
                if (!method.TryGetBody(out body) || !body.HasInstructions)
                {
                    effects = null;
                    return false;
                }

                int callDepth = 0;
                int offset = 0;
                Instruction instruction;
                OpCode prevOpcode = OpCodes.Nop;

                //Stack for load instructions
                Field lastAccessedArrayField = null;
                Field lastAccessedField = null;

                while (body.TryGetInstruction(offset, out instruction))
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (LdcOpCodes.Contains(opCode))
                    {
                        //topIsConstant = true;
                    }
                    else if (ConvOpCodes.Contains(opCode))
                    {
                        // do not change topIsConstant
                    }
                    else
                    {
                        if (opCode == OpCodes.Stfld)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field field = instruction.Field;
                            AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type);
                        }
                        else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field accessedField = instruction.Field;

                            if (accessedField.Type.Spec == TypeSpec.SzArray)
                            {
                                lastAccessedArrayField = accessedField;
                            }
                            else
                                lastAccessedField = accessedField;
                        }
                        else if (StElemOpCodes.Contains(opCode))
                        {
                            if (lastAccessedArrayField != null)
                            {
                                //Indicates that there is n array type modified
                                AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type);
                                lastAccessedArrayField = null;
                            }
                        }
                        else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                            Method methodinner = instruction.Method;
                            SafeDebug.AssumeNotNull(method, "method");

                            directCalledMethods.Add(methodinner);
                            TypeEx methodDeclaringType;

                            //are these function calls are within the parent types
                            if (methodinner.TryGetDeclaringType(out methodDeclaringType) &&
                                declaringType.IsAssignableTo(methodDeclaringType))
                            {
                                MethodEffects methodEffects;
                                if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects))
                                {
                                    res.AddRange(methodEffects.WrittenInstanceFields);
                                    foreach (var key in methodEffects.ModificationTypeDictionary.Keys)
                                        modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key];
                                    directSetFields.AddRange(methodEffects.DirectSetterFields);
                                    if (methodEffects.CallDepth > callDepth)
                                        callDepth = methodEffects.CallDepth;
                                }
                            }
                            else
                            {
                                //introducing heuristics for inter-procedural static analysis
                                if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType &&
                                    !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get")
                                    || methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set")))
                                {
                                    AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic,
                                        prevOpcode, lastAccessedField, lastAccessedField.Type);
                                }
                            }
                        }
                        else if (opCode == OpCodes.Ret)
                        {
                            if (instruction.Field != null)
                                returnFields.Add(instruction.Field);
                        }
                        //topIsConstant = false;
                    }

                    prevOpcode = opCode;
                    offset = instruction.NextOffset;
                }

                effects = new MethodEffects((IFiniteSet<string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1);
                psd.MethodEffectsDic[method.GlobalIndex] = effects;
                return true;
            }
            catch (Exception ex)
            {
                host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects",
                    "Failed to compute method effects for method " + method.FullName + "," + ex.Message);
                effects = null;
                return false;
            }
        }
        /// <summary>
        /// Gets the target method that need to be invoked for setting a field.
        /// Based on static analysis and later uses dynamic analysis for giving
        /// more priority to those methods that are identified through dynamic analysis also.
        /// </summary>
        /// <param name="ucls"></param>
        /// <param name="targetField"></param>
        /// <param name="declaringType"></param>
        /// <param name="targetMethods"></param>
        /// <returns></returns>
        private bool GetTargetMethod(UncoveredCodeLocationStore ucls, Field targetField,
                                     out SafeSet <Method> targetMethods)
        {
            targetMethods = new SafeSet <Method>();

            int numfields = ucls.AllFields.Count;

            for (int count = 0; count < numfields; count++)
            {
                var field = ucls.AllFields[count];

                //Get all write methods for this field
                SafeSet <Method> writeMethods = null;

                //Get the declaring type of the field. There are two possibilities of choosing
                //a declaring type: from the next field or the enclosing type
                TypeEx declaringType1 = null, declaringType2 = null;

                //If there is a parent field, the declaring type should
                //be upgraded to the type of the next field in the list, which could be
                //a sub-class of the actual declaring type
                if (count < numfields - 1)
                {
                    var nextField = ucls.AllFields[count + 1];
                    declaringType1 = nextField.Type;
                }

                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(this.host, field, out declaringType2))
                {
                    SafeDebug.AssumeNotNull(declaringType2, "declaringType");
                }

                var declaringType = declaringType2;
                if (declaringType1 != null && declaringType1 != declaringType2)
                {
                    declaringType = this.ChooseADeclaringType(declaringType1, declaringType2);
                }

                //Chosen declaringType should be a part of all field types stored
                //in UCLS. If not, there can be inheritance issues
                if (!ucls.AllFieldTypes.Contains(declaringType))
                {
                    //Find out the type to which declaringType is assignable and update it
                    foreach (var tex in ucls.AllFieldTypes)
                    {
                        if (tex.IsAssignableTo(declaringType))
                        {
                            declaringType = tex;
                            break;
                        }
                    }
                }

                //For the first field, get all the methods that modify the field
                //using static analysis
                if (targetMethods.Count == 0)
                {
                    //Try from static analysis store
                    if (!this.psd.TryGetFilteredWriteMethods(field, declaringType, ucls.DesiredFieldModificationType, out writeMethods))
                    {
                        this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                 "Failed to get write methods for the field " + field.FullName);
                        return(false);
                    }

                    //Try from dynamic analysis
                    //if (!this.pmd.FieldDictionary.TryGetValue(field.GlobalIndex, out fs))
                    targetMethods.AddRange(writeMethods);
                }
                else
                {
                    //Get the callers of all methods in targetmethods
                    SafeSet <Method> callerMethods = new SafeSet <Method>();
                    foreach (var tmw in targetMethods)
                    {
                        SafeSet <Method> callingMethods;

                        //TODO: Performance improvements can be done here as we repeat the loops inside
                        //the method for each method in targetMethods
                        if (!this.psd.TryGetCallingMethodsInType(tmw, field, declaringType, out callingMethods))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                     SafeString.Format("Failed to get calling methods of {0} through static and dynamic analysis", tmw));
                            continue;
                        }

                        //Filter the called methods based on field to avoid
                        //unnecessary additional methods
                        SafeSet <Method> subcallingMethods = this.psd.FilterCallingMethodsBasedOnField(tmw, field, callingMethods);
                        if (callingMethods.Count > 0 && subcallingMethods.Count == 0)
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "callingmethods",
                                                     "Failed to filter calling methods based on field, adding all methods");
                            subcallingMethods.AddRange(callingMethods);
                        }

                        //Check in dynamic analysis portion
                        //if (!this.pmd.MethodDictionary.TryGetValue(tmw.GlobalIndex, out mstore))
                        //{
                        //}
                        //else
                        //    callingMethods = mstore.CallingMethods[declaringType];

                        callerMethods.AddRange(subcallingMethods);
                    }

                    //All caller methods in the parent type
                    targetMethods = callerMethods;
                }

                //Our objective is to search for the methods that belong to our target field.
                //Stop traversal once the desired method is found
                if (field == targetField)
                {
                    break;
                }
            }

            return(true);
        }
        private void GetCallingMethods(Field field, TypeEx declaringType, SafeSet<Method> writeMethods, SafeSet<Method> newWriteMethods)
        {
            foreach (var writeM in writeMethods)
            {
                if (writeM.Definition.DeclaredVisibility != Visibility.Private || writeM.IsConstructor)
                {
                    newWriteMethods.Add(writeM);
                    continue;
                }

                //Get other calling methods within this type
                SafeSet<Method> localCM;
                if (this.TryGetCallingMethodsInType(writeM, field, declaringType, out localCM))
                {
                    newWriteMethods.AddRange(localCM);
                }
            }
        }
        /// <summary>
        /// Includes filtering of the methods based on desired format
        /// </summary>
        /// <returns></returns>
        public bool TryGetFilteredWriteMethods(Field field, TypeEx declaringType, FieldModificationType desiredfmt, out SafeSet<Method> writeMethods)
        {
            //Check in the predefined store before proceeding
            if (PreDefinedMethodEffects.TryGetWriteMethods(this, field, desiredfmt, out writeMethods))
            {
                SafeSet<Method> newWriteMethods = new SafeSet<Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);

                //Filter those methods whose actual types are abstract
                SafeSet<Method> returnMethods = new SafeSet<Method>();
                foreach (Method m in writeMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                foreach (Method m in newWriteMethods)
                {
                    TypeEx declType;
                    if (m.TryGetDeclaringType(out declType) && !declType.IsAbstract && !declType.IsInterface)
                    {
                        returnMethods.Add(m);
                    }
                }

                writeMethods.Clear();
                writeMethods.AddRange(returnMethods);
                return true;
            }

            //Identify those method that directly modify this field
            if (!TryGetWriteMethods(field, declaringType, out writeMethods))
                return false;

            //C# supports properties. In that case, the property setter can also
            //be a viable method. add property setter and its callers also
            Property property;
            if (MethodOrFieldAnalyzer.TryGetPropertyModifyingField(this, declaringType, field, out property))
            {
                if (property.IsVisible(VisibilityContext.Exported))
                    writeMethods.Add(property.Setter);

                var newWriteMethods = new SafeSet<Method>();
                GetCallingMethods(field, declaringType, writeMethods, newWriteMethods);
                writeMethods.AddRange(newWriteMethods);
            }

            writeMethods = FilterWriteMethodsOfUpdateType(field, desiredfmt, writeMethods);
            return true;
        }
        /// <summary>
        /// Gets calling methods of a given called method on the given field in a given target type
        /// </summary>
        /// <returns></returns>
        public bool TryGetCallingMethodsInType(Method calledMethod, Field field, TypeEx targetType, out SafeSet<Method> callingMethods)
        {
            SafeDebug.AssumeNotNull(calledMethod, "method");
            SafeDebug.AssumeNotNull(targetType, "type");

            //Get the associated property of the field
            Property property;
            if (!MethodOrFieldAnalyzer.TryGetPropertyReadingField(this, targetType, field, out property))
            {
                //TODO: error;
            }

            MethodStore mstore = null;
            if (this.MethodDictionary.TryGetValue(calledMethod, out mstore))
            {
                if (mstore.CallingMethods.TryGetValue(targetType, out callingMethods))
                    return true;
            }

            //No method store found. create a fresh one
            if (mstore == null)
            {
                mstore = new MethodStore();
                mstore.methodName = calledMethod;
                this.MethodDictionary[calledMethod] = mstore;
            }

            callingMethods = new SafeSet<Method>();
            mstore.CallingMethods[targetType] = callingMethods;
            TypeEx calledMethodType;
            if (!calledMethod.TryGetDeclaringType(out calledMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                    "Failed to get the declaring type for the method " + calledMethod.FullName);
                return false;
            }

            //Needs to addess the array type issue over here.
            var targetdef = targetType.Definition;
            if (targetdef == null)
            {
                if (targetType.TypeKind != TypeKind.SzArrayElements)
                {
                    this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                        "The definition for the type " + targetType.FullName + " is null");
                    return false;
                }
                else
                {
                    targetdef = targetType.ElementType.Definition;
                }
            }

            //Analyze each method in the given type to identify the calling methods
            //of the given method
            foreach (var typeMethod in targetdef.DeclaredInstanceMethods)
            {
                Method minstance = typeMethod.Instantiate(targetType.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(this, typeMethod));

                MethodEffects meffects;
                if (!MethodOrFieldAnalyzer.TryComputeMethodEffects(this, targetType, minstance, null, out meffects))
                    continue;

                //Check for a direct comparison
                if (meffects.DirectCalledMethods.Contains(calledMethod))
                    callingMethods.Add(minstance);
                else
                {
                    //Use vtable lookup for addressing the abstract issues
                    foreach (var dcallMethod in meffects.DirectCalledMethods)
                    {
                        if (dcallMethod.IsConstructor)
                            continue;

                        TypeEx dcallMethodType;
                        if (dcallMethod.TryGetDeclaringType(out dcallMethodType))
                        {
                            if (dcallMethodType == calledMethodType || !dcallMethodType.IsAbstract || !dcallMethodType.IsInterface)
                                continue;

                            if (!dcallMethodType.IsAssignableTo(calledMethodType) && !calledMethodType.IsAssignableTo(dcallMethodType))
                                continue;
                        }

                        try
                        {
                            var lookupMethod = calledMethodType.VTableLookup(dcallMethod);
                            if (lookupMethod != null && calledMethod == lookupMethod)
                            {
                                callingMethods.Add(minstance);
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Log.LogWarningFromException(ex, WikiTopics.MissingWikiTopic,
                                "vtablelookup", "Failed to perform vtablelookup for " + dcallMethod.FullName + " in type " + calledMethodType.FullName);
                        }
                    }
                }
            }

            //Check whether there are any private methods in calling methods.
            //If yes, replace them with their callers.
            if (!PexMeConstants.DISABLE_CALLING_METHODS_WITHIN_CLASS)
            {
                var newCallingMethods = new SafeSet<Method>();
                foreach (var callingM in callingMethods)
                {
                    if (callingM.Definition.DeclaredVisibility != Visibility.Private || callingM.IsConstructor)
                    {
                        newCallingMethods.Add(callingM);
                        continue;
                    }

                    //Get other calling methods within this type
                    SafeSet<Method> localCM;
                    if (this.TryGetCallingMethodsInType(callingM, field, targetType, out localCM))
                    {
                        newCallingMethods.AddRange(localCM);
                    }
                }

                callingMethods.Clear();
                callingMethods.AddRange(newCallingMethods);
            }

            //Needs to further analyze parent types
            TypeEx baseType = targetType.BaseType;
            if (baseType != null && baseType.FullName != "System.Object")   //TODO: Avoid string comparisons. needs to figure out how to do that
            {
                SafeSet<Method> baseCallingMethods;
                TryGetCallingMethodsInType(calledMethod, field, baseType, out baseCallingMethods);
                callingMethods.AddRange(baseCallingMethods);
            }

            return true;
        }
        /// <summary>
        /// Populates all pair-wise combinations of defs and uses identified through static analysis
        /// </summary>
        public void PopulateDUCoverTable()
        {
            DUCoverStore dcs = DUCoverStore.GetInstance();

            SafeSet<FieldDefUseStore> allDefs = new SafeSet<FieldDefUseStore>();
            allDefs.AddRange(this.DefDic.Keys);
            allDefs.AddRange(this.DefOrUseSet);

            SafeSet<FieldDefUseStore> allUses = new SafeSet<FieldDefUseStore>();
            allUses.AddRange(this.UseDic.Keys);
            allUses.AddRange(this.DefOrUseSet);
            int numInfeasible = 0;

            //Compute pair-wise combinations
            foreach (var defEntry in allDefs)
            {
                foreach (var useEntry in allUses)
                {
                    //Ignore the trivial entries that involve just a combination of setter and getter methods
                    if (defEntry.Method.ShortName.StartsWith("set_") && useEntry.Method.ShortName.StartsWith("get_"))
                        continue;
                    if (!this.IsFeasibleDUCoverEntry(dcs, defEntry, useEntry))
                    {
                        numInfeasible++;
                        continue;
                    }

                    DUCoverStoreEntry dcse = new DUCoverStoreEntry(this.fd, defEntry.Method, defEntry.Offset,
                        useEntry.Method, useEntry.Offset);

                    if (defEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Def_UnknownSideEffectMethod = defEntry.UnknownSideEffectMethod;
                        dcse.DefUnsure = true;
                    }

                    if (useEntry.UnknownSideEffectMethod != null)
                    {
                        dcse.Use_UnknownSideEffectMethod = useEntry.UnknownSideEffectMethod;
                        dcse.UseUnsure = true;
                    }

                    if(!this.duCoverageTable.ContainsKey(dcse))
                        this.duCoverageTable[dcse] = 0;
                }
            }

            //Clear all the cached entries.
            this.feasibilityDicCache.Clear();

            logger.Debug("Detected infeasible du-pairs for field " + this.fd.FullName + "(" + numInfeasible + ")");
        }
        /// <summary>
        /// Gets calling methods of a given called method on the given field in a given target type
        /// </summary>
        /// <returns></returns>
        public bool TryGetCallingMethodsInType(Method calledMethod, Field field, TypeEx targetType, out SafeSet <Method> callingMethods)
        {
            SafeDebug.AssumeNotNull(calledMethod, "method");
            SafeDebug.AssumeNotNull(targetType, "type");

            //Get the associated property of the field
            Property property;

            if (!MethodOrFieldAnalyzer.TryGetPropertyReadingField(this, targetType, field, out property))
            {
                //TODO: error;
            }

            MethodStore mstore = null;

            if (this.MethodDictionary.TryGetValue(calledMethod, out mstore))
            {
                if (mstore.CallingMethods.TryGetValue(targetType, out callingMethods))
                {
                    return(true);
                }
            }

            //No method store found. create a fresh one
            if (mstore == null)
            {
                mstore            = new MethodStore();
                mstore.methodName = calledMethod;
                this.MethodDictionary[calledMethod] = mstore;
            }

            callingMethods = new SafeSet <Method>();
            mstore.CallingMethods[targetType] = callingMethods;
            TypeEx calledMethodType;

            if (!calledMethod.TryGetDeclaringType(out calledMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                                  "Failed to get the declaring type for the method " + calledMethod.FullName);
                return(false);
            }

            //Needs to addess the array type issue over here.
            var targetdef = targetType.Definition;

            if (targetdef == null)
            {
                if (targetType.TypeKind != TypeKind.SzArrayElements)
                {
                    this.Log.LogError(WikiTopics.MissingWikiTopic, "callingmethods",
                                      "The definition for the type " + targetType.FullName + " is null");
                    return(false);
                }
                else
                {
                    targetdef = targetType.ElementType.Definition;
                }
            }

            //Analyze each method in the given type to identify the calling methods
            //of the given method
            foreach (var typeMethod in targetdef.DeclaredInstanceMethods)
            {
                Method minstance = typeMethod.Instantiate(targetType.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(this, typeMethod));

                MethodEffects meffects;
                if (!MethodOrFieldAnalyzer.TryComputeMethodEffects(this, targetType, minstance, null, out meffects))
                {
                    continue;
                }

                //Check for a direct comparison
                if (meffects.DirectCalledMethods.Contains(calledMethod))
                {
                    callingMethods.Add(minstance);
                }
                else
                {
                    //Use vtable lookup for addressing the abstract issues
                    foreach (var dcallMethod in meffects.DirectCalledMethods)
                    {
                        if (dcallMethod.IsConstructor)
                        {
                            continue;
                        }

                        TypeEx dcallMethodType;
                        if (dcallMethod.TryGetDeclaringType(out dcallMethodType))
                        {
                            if (dcallMethodType == calledMethodType || !dcallMethodType.IsAbstract || !dcallMethodType.IsInterface)
                            {
                                continue;
                            }

                            if (!dcallMethodType.IsAssignableTo(calledMethodType) && !calledMethodType.IsAssignableTo(dcallMethodType))
                            {
                                continue;
                            }
                        }

                        try
                        {
                            var lookupMethod = calledMethodType.VTableLookup(dcallMethod);
                            if (lookupMethod != null && calledMethod == lookupMethod)
                            {
                                callingMethods.Add(minstance);
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Log.LogWarningFromException(ex, WikiTopics.MissingWikiTopic,
                                                             "vtablelookup", "Failed to perform vtablelookup for " + dcallMethod.FullName + " in type " + calledMethodType.FullName);
                        }
                    }
                }
            }

            //Check whether there are any private methods in calling methods.
            //If yes, replace them with their callers.
            if (!PexMeConstants.DISABLE_CALLING_METHODS_WITHIN_CLASS)
            {
                var newCallingMethods = new SafeSet <Method>();
                foreach (var callingM in callingMethods)
                {
                    if (callingM.Definition.DeclaredVisibility != Visibility.Private || callingM.IsConstructor)
                    {
                        newCallingMethods.Add(callingM);
                        continue;
                    }

                    //Get other calling methods within this type
                    SafeSet <Method> localCM;
                    if (this.TryGetCallingMethodsInType(callingM, field, targetType, out localCM))
                    {
                        newCallingMethods.AddRange(localCM);
                    }
                }

                callingMethods.Clear();
                callingMethods.AddRange(newCallingMethods);
            }

            //Needs to further analyze parent types
            TypeEx baseType = targetType.BaseType;

            if (baseType != null && baseType.FullName != "System.Object")   //TODO: Avoid string comparisons. needs to figure out how to do that
            {
                SafeSet <Method> baseCallingMethods;
                TryGetCallingMethodsInType(calledMethod, field, baseType, out baseCallingMethods);
                callingMethods.AddRange(baseCallingMethods);
            }

            return(true);
        }