/// <summary>
        /// Function that retrieves associated method store 
        /// </summary>
        /// <param name="pms"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public static bool TryGetMethodStore(IPexComponent host, PersistentMethodStore pms, out MethodStore ms)
        {
            ms = new MethodStore();

            bool bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, pms.methodName, out ms.methodName);
            SafeDebug.Assume(bresult, "Failed to get the method from persistent form " + pms.methodName);

            foreach (var fieldstr in pms.ReadFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.ReadFields.Add(field);
            }

            foreach (var fieldstr in pms.WriteFields)
            {
                Field field;
                bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get the field from persistent form " + fieldstr);
                ms.WriteFields.Add(field);
            }

            foreach (var typeexstr in pms.CallingMethods.Keys)
            {
                SafeSet<Method> wmethods = new SafeSet<Method>();
                TypeEx typeEx;
                bresult = MethodOrFieldAnalyzer.TryGetTypeExFromPersistentStringForm(host, typeexstr, out typeEx);
                if (!bresult)
                {
                    //No strict safedebugging cannot be added for calling methods since there
                    //can be several dummy methods from Pex side
                    continue;
                }

                ms.CallingMethods.Add(typeEx, wmethods);

                var methods = pms.CallingMethods[typeexstr];
                foreach (var mstr in methods)
                {
                    Method method;
                    bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, mstr, out method);
                    if (!bresult)
                        continue;
                    wmethods.Add(method);
                }
            }

            foreach (var calledMethodStr in pms.CalledMethods)
            {
                Method method;
                bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, calledMethodStr, out method);
                if (!bresult)
                    continue;
                ms.CalledMethods.Add(method);
            }

            return true;
        }
Esempio n. 2
0
        /// <summary>
        /// Gets a method store from a method signature
        /// </summary>
        /// <param name="msignature"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public bool TryGetMethodStoreFromSignature(string msignature, out MethodStore ms)
        {
            foreach (var key in this.MethodDictionary.Keys)
            {
                string keysig = MethodOrFieldAnalyzer.GetMethodSignature(key);
                if (keysig == msignature)
                {
                    ms = this.MethodDictionary[key];
                    return(true);
                }
            }

            ms = null;
            return(false);
        }
Esempio n. 3
0
        /// <summary>
        /// Makes a mapping relationship between a calling method and a called method
        /// </summary>
        /// <param name="callingMethod"></param>
        /// <param name="calledMethod"></param>
        public void AddMethodMapping(Method callingMethod, Method calledMethod)
        {
            //Updating the method store for calling methods
            MethodStore callingMethodStore = null;

            if (!methodDic.TryGetValue(callingMethod, out callingMethodStore))
            {
                callingMethodStore            = new MethodStore();
                callingMethodStore.methodName = calledMethod;
                methodDic[callingMethod]      = callingMethodStore;
            }
            callingMethodStore.CalledMethods.Add(calledMethod);

            //Updating the method store for called methods
            MethodStore calledMethodStore = null;

            if (!methodDic.TryGetValue(calledMethod, out calledMethodStore))
            {
                calledMethodStore            = new MethodStore();
                calledMethodStore.methodName = calledMethod;
                methodDic[calledMethod]      = calledMethodStore;
            }

            TypeEx callingMethodType;

            if (!callingMethod.TryGetDeclaringType(out callingMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "methodmapping",
                                  "Failed to get the declared type for method " + calledMethod);
                return;
            }

            SafeSet <Method> localCallingMethods;

            if (!calledMethodStore.CallingMethods.TryGetValue(callingMethodType, out localCallingMethods))
            {
                localCallingMethods = new SafeSet <Method>();
                calledMethodStore.CallingMethods[callingMethodType] = localCallingMethods;
            }
            localCallingMethods.Add(callingMethod);
        }
        /// <summary>
        /// Function the retrieves associated Persistent store for each MethodStore
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="pms"></param>
        /// <returns></returns>
        public static bool TryGetPersistentMethodStore(MethodStore ms, out PersistentMethodStore pms)
        {
            pms = new PersistentMethodStore();
            pms.methodName = MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(ms.methodName);

            //foreach (var field in ms.ReadFields)
            //    pms.ReadFields.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfField(field));

            foreach (var field in ms.WriteFields)
                pms.WriteFields.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfField(field));

            //foreach (var typeex in ms.CallingMethods.Keys)
            //{
            //    HashSet<string> wmethods = new HashSet<string>();
            //    pms.CallingMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfTypeEx(typeex), wmethods);

            //    var methods = ms.CallingMethods[typeex];
            //    var assemblyname = typeex.Definition.Module.Assembly.Location;
            //    var typename = typeex.FullName;

            //    foreach (var m in methods)
            //    {
            //        wmethods.Add(assemblyname + PexMeConstants.PexMePersistenceFormSeparator
            //            + typename + PexMeConstants.PexMePersistenceFormSeparator
            //            + MethodOrFieldAnalyzer.GetMethodSignature(m));
            //    }
            //}

            //foreach (var calledMethod in ms.CalledMethods)
            //    pms.CalledMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(calledMethod));

            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;
        }
Esempio n. 6
0
        /// <summary>
        /// Adds a monitored field to the database. Updates two kinds of hashmaps
        /// a. Field to Method mapper, which gives what the methods modifying a given field
        /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods)
        /// </summary>
        /// <param name="tm"></param>
        /// <param name="method"></param>
        /// <param name="f"></param>
        /// <param name="indices"></param>
        /// <param name="fieldValue"></param>
        public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue)
        {
            string arrayIndex = "";

            using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm))
            {
                fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field
                //if (indices.Length == 0) //not an array-type field
                if (indices.Length == 1)                                          //is an array-type field
                {
                    arrayIndex = " at index of " + indices[0].UniqueIndex.ToString();
                }

                if (initialValue != null)
                {
                    initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue);
                }
            }

            //Updating the method store
            MethodStore ms;

            if (!methodDic.TryGetValue(method, out ms))
            {
                ms                = new MethodStore();
                ms.methodName     = method;
                methodDic[method] = ms;
            }

            ms.WriteFields.Add(f);
            //TODO: Gather information of read fields

            //Updating the field store
            FieldStore fs;

            if (!fieldDic.TryGetValue(f, out fs))
            {
                fs           = new FieldStore();
                fs.FieldName = f;
                fieldDic[f]  = fs;
            }

            TypeEx declaringType;

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

            SafeSet <Method> writeMethods;

            if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods))
            {
                writeMethods = new SafeSet <Method>();
                fs.WriteMethods[declaringType] = writeMethods;
            }
            writeMethods.Add(method);

            var sb      = new SafeStringBuilder();
            var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false);

            swriter.Write(fieldValue);
            sb.Append(arrayIndex);

            int value;

            if (tm.TryGetI4Constant(fieldValue, out value))
            {
                int initialval;
                if (initialValue != null)
                {
                    tm.TryGetI4Constant(initialValue, out initialval);
                }
                else
                {
                    initialval = 0;
                }

                sb.Append("  constant value: " + value);

                if (f.Type.ToString() != "System.Boolean")
                {
                    if (value < initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT;
                    }
                    else if (value > initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT;

                        if (value == initialval + 1)
                        {
                            fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE;
                        }
                    }
                    else
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                    }
                }
                else
                {
                    if (value == 0)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET;
                    }
                    else
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET;
                    }
                }
            }
            else if (tm.IsDefaultValue(fieldValue))
            {
                if (initialValue != null && !tm.IsDefaultValue(initialValue))
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET;
                }
                else
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }

                sb.Append("  null reference ");
            }
            else
            {
                if (initialValue == null)
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET;
                }
                else
                {
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }

                sb.Append("  not-null reference ");
            }

            fs.FieldValues.Add(sb.ToString());
        }
        /// <summary>
        /// Gets a method store from a method signature
        /// </summary>
        /// <param name="msignature"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        public bool TryGetMethodStoreFromSignature(string msignature, out MethodStore ms)
        {
            foreach (var key in this.MethodDictionary.Keys)
            {
                string keysig = MethodOrFieldAnalyzer.GetMethodSignature(key);
                if (keysig == msignature)
                {
                    ms = this.MethodDictionary[key];
                    return true;
                }
            }

            ms = null;
            return false;
        }
        /// <summary>
        /// Adds a monitored field to the database. Updates two kinds of hashmaps
        /// a. Field to Method mapper, which gives what the methods modifying a given field
        /// b. Method to Field mapper, which gives what fields are modified by each method (later used to identify a minimized set of methods)
        /// </summary>
        /// <param name="tm"></param>
        /// <param name="method"></param>
        /// <param name="f"></param>
        /// <param name="indices"></param>
        /// <param name="fieldValue"></param>
        public void AddMonitoredField(TermManager tm, Method method, Field f, Term[] indices, Term fieldValue, Term initialValue)
        {
            string arrayIndex = "";
            using (PexMeTermRewriter pexmeRewriter = new PexMeTermRewriter(tm))
            {
                fieldValue = pexmeRewriter.VisitTerm(default(TVoid), fieldValue); //update the field value to accomodate array-type field
                //if (indices.Length == 0) //not an array-type field
                if (indices.Length == 1) //is an array-type field
                {
                    arrayIndex = " at index of " + indices[0].UniqueIndex.ToString();
                }

                if(initialValue != null)
                    initialValue = pexmeRewriter.VisitTerm(default(TVoid), initialValue);
            }

            //Updating the method store
            MethodStore ms;
            if(!methodDic.TryGetValue(method, out ms))
            {
                ms = new MethodStore();
                ms.methodName = method;
                methodDic[method] = ms;
            }

            ms.WriteFields.Add(f);
            //TODO: Gather information of read fields

            //Updating the field store
            FieldStore fs;
            if (!fieldDic.TryGetValue(f, out fs))
            {
                fs = new FieldStore();
                fs.FieldName = f;
                fieldDic[f] = fs;
            }

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

            SafeSet<Method> writeMethods;
            if (!fs.WriteMethods.TryGetValue(declaringType, out writeMethods))
            {
                writeMethods = new SafeSet<Method>();
                fs.WriteMethods[declaringType] = writeMethods;
            }
            writeMethods.Add(method);

            var sb = new SafeStringBuilder();
            var swriter = new TermSExpWriter(tm, new SafeStringWriter(sb), true, false);
            swriter.Write(fieldValue);
            sb.Append(arrayIndex);

            int value;
            if (tm.TryGetI4Constant(fieldValue, out value))
            {
                int initialval;
                if (initialValue != null)
                    tm.TryGetI4Constant(initialValue, out initialval);
                else
                    initialval = 0;

                sb.Append("  constant value: " + value);

                if (f.Type.ToString() != "System.Boolean")
                {
                    if (value < initialval)
                        fs.ModificationTypeDictionary[method] = FieldModificationType.DECREMENT;
                    else if (value > initialval)
                    {
                        fs.ModificationTypeDictionary[method] = FieldModificationType.INCREMENT;

                        if (value == initialval + 1)
                            fs.PreciseModificationTypeDictionary[method] = FieldModificationType.INCREMENT_ONE;
                    }
                    else
                        fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;
                }
                else
                {
                    if (value == 0)
                        fs.ModificationTypeDictionary[method] = FieldModificationType.FALSE_SET;
                    else
                        fs.ModificationTypeDictionary[method] = FieldModificationType.TRUE_SET;
                }
            }
            else if (tm.IsDefaultValue(fieldValue))
            {
                if (initialValue != null && !tm.IsDefaultValue(initialValue))
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NULL_SET;
                else
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;

                sb.Append("  null reference ");
            }
            else
            {
                if (initialValue == null)
                    fs.ModificationTypeDictionary[method] = FieldModificationType.NON_NULL_SET;
                else
                    fs.ModificationTypeDictionary[method] = FieldModificationType.UNKNOWN;

                sb.Append("  not-null reference ");
            }

            fs.FieldValues.Add(sb.ToString());
        }
        /// <summary>
        /// Makes a mapping relationship between a calling method and a called method
        /// </summary>
        /// <param name="callingMethod"></param>
        /// <param name="calledMethod"></param>
        public void AddMethodMapping(Method callingMethod, Method calledMethod)
        {
            //Updating the method store for calling methods
            MethodStore callingMethodStore = null;
            if (!methodDic.TryGetValue(callingMethod, out callingMethodStore))
            {
                callingMethodStore = new MethodStore();
                callingMethodStore.methodName = calledMethod;
                methodDic[callingMethod] = callingMethodStore;
            }
            callingMethodStore.CalledMethods.Add(calledMethod);

            //Updating the method store for called methods
            MethodStore calledMethodStore = null;
            if(!methodDic.TryGetValue(calledMethod, out calledMethodStore))
            {
                calledMethodStore = new MethodStore();
                calledMethodStore.methodName = calledMethod;
                methodDic[calledMethod] = calledMethodStore;
            }

            TypeEx callingMethodType;
            if (!callingMethod.TryGetDeclaringType(out callingMethodType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "methodmapping",
                    "Failed to get the declared type for method " + calledMethod);
                return;
            }

            SafeSet<Method> localCallingMethods;
            if (!calledMethodStore.CallingMethods.TryGetValue(callingMethodType, out localCallingMethods))
            {
                localCallingMethods = new SafeSet<Method>();
                calledMethodStore.CallingMethods[callingMethodType] = localCallingMethods;
            }
            localCallingMethods.Add(callingMethod);
        }
        /// <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);
        }