public void ReplaceCurrent(NameAnalyzer analyzer, MethodReference newCurrent)
        {
            if (Current == newCurrent || OpenCurrent == newCurrent)
            {
                return;
            }

            MethodReference m = (((OpenCurrent ?? Current) ?? OpenRoot) ?? Root).Resolve();    //Interface method -> Empty slot

            if (m != null)
            {
                var renRef        = (m as IAnnotationProvider).Annotations[NameAnalyzer.RenRef] as List <IReference>;
                var newCurrentDef = newCurrent.Resolve();
                var renId         = (newCurrentDef as IAnnotationProvider).Annotations[NameAnalyzer.RenId] as Identifier?;
                if (analyzer.Assemblies.Contains(newCurrentDef.Module.Assembly))
                {
                    analyzer.Cr.Database.AddEntry(NameAnalyzer.DB_SRC, newCurrent.FullName, string.Format("Virtual override @ {0} => Not renamed", m.FullName));
                }
                (newCurrentDef as IAnnotationProvider).Annotations[NameAnalyzer.RenOk] = false;
                if (renRef != null)
                {
                    renRef.Add(new VirtualMethodReference(newCurrentDef));
                }
            }
            Current     = newCurrent;
            OpenCurrent = null;
        }
        public void ReplaceRoot(NameAnalyzer analyzer, MethodReference newRoot)
        {
            if (Root == newRoot || OpenRoot == newRoot)
            {
                return;
            }

            var renRef = (newRoot.Resolve() as IAnnotationProvider).Annotations[NameAnalyzer.RenRef] as List <IReference>;
            var root   = (OpenRoot ?? Root).Resolve();
            var renId  = (root as IAnnotationProvider).Annotations[NameAnalyzer.RenId] as Identifier?;

            if (analyzer.Assemblies.Contains(root.Module.Assembly))
            {
                analyzer.Cr.Database.AddEntry(NameAnalyzer.DB_SRC, root.FullName, string.Format("Virtual override @ {0} => Not renamed", newRoot.FullName));
            }
            (root as IAnnotationProvider).Annotations[NameAnalyzer.RenOk] = false;
            if (renRef != null && renId != null)
            {
                renRef.Add(new VirtualMethodReference(root));
            }
            Root     = newRoot;
            OpenRoot = null;
        }
        public static VTable GetVTable(NameAnalyzer analyzer, TypeDefinition typeDef, Dictionary <TypeDefinition, VTable> tbls)
        {
            if (tbls.ContainsKey(typeDef))
            {
                return(tbls[typeDef]);
            }

            //Partition II 10.3, 12.2

            VTable ret = new VTable()
            {
                TypeDef = typeDef
            };

            TypeDefinition baseType = null;

            if (typeDef.BaseType != null)
            {
                baseType = typeDef.BaseType.Resolve();
                if (baseType != null)
                {
                    ret.Table = new List <VTableSlot>(GetVTable(analyzer, baseType, tbls).Table);
                    if (typeDef.BaseType is GenericInstanceType)
                    {
                        GenericInstanceType genInst = typeDef.BaseType as GenericInstanceType;
                        for (int i = 0; i < ret.Table.Count; i++)
                        {
                            ret.Table[i]             = ret.Table[i].Clone();
                            ret.Table[i].OpenCurrent = ret.Table[i].Current;
                            ret.Table[i].Current     = Resolve(ret.Table[i].OpenCurrent, genInst);
                            ret.Table[i].OpenRoot    = ret.Table[i].Root;
                            ret.Table[i].Root        = Resolve(ret.Table[i].OpenRoot, genInst);
                        }
                    }
                }
                else
                {
                    ret.Table = new List <VTableSlot>();
                }
            }
            else
            {
                ret.Table = new List <VTableSlot>();
            }

            if (typeDef.HasInterfaces)          //Interface methods
            {
                foreach (var i in typeDef.Interfaces)
                {
                    if (baseType != null && baseType.Interfaces.Contains(i))
                    {
                        continue;
                    }

                    TypeDefinition iface = i.Resolve();
                    if (iface == null)
                    {
                        continue;
                    }
                    GenericInstanceType genInst = i as GenericInstanceType;
                    foreach (var j in iface.Methods)
                    {
                        MethodReference ifaceMethod = j;
                        if (genInst != null)
                        {
                            ifaceMethod = Resolve(ifaceMethod, genInst);
                        }


                        VTableSlot slot = null;
                        for (int k = 0; k < ret.Table.Count; k++)
                        {
                            if (Match(ifaceMethod, ret.Table[k].Root))
                            {
                                slot = ret.Table[k];
                                break;
                            }
                        }
                        if (slot == null)
                        {
                            if (genInst != null)
                            {
                                ret.Table.Add(new VTableSlot()
                                {
                                    Root     = ifaceMethod,
                                    OpenRoot = j,
                                    Current  = null
                                });
                            }
                            else
                            {
                                ret.Table.Add(new VTableSlot()
                                {
                                    Root    = ifaceMethod,
                                    Current = null
                                });
                            }
                        }
                        else
                        {
                            slot.ReplaceRoot(analyzer, j);
                        }
                    }
                }
            }

            foreach (var i in typeDef.Methods)  //Interface virtual newslot
            {
                if (!i.IsVirtual || !i.IsNewSlot)
                {
                    continue;
                }
                for (int j = 0; j < ret.Table.Count; j++)
                {
                    if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root))
                    {
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
                }
            }
            foreach (var i in typeDef.Methods)  //Interface virtual
            {
                if (!i.IsVirtual)
                {
                    continue;
                }
                for (int j = 0; j < ret.Table.Count; j++)
                {
                    if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root))
                    {
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
                }
            }
            foreach (var i in typeDef.Methods)  //Base newslot
            {
                if (!i.IsVirtual || !i.IsNewSlot)
                {
                    continue;
                }
                for (int j = 0; j < ret.Table.Count; j++)
                {
                    if (Match(i, ret.Table[j].Current))
                    {
                        ret.Table[j].Root = i;
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
                }
            }
            foreach (var i in typeDef.Methods)  //Base virtual
            {
                if (!i.IsVirtual)
                {
                    continue;
                }
                for (int j = 0; j < ret.Table.Count; j++)
                {
                    if (i != ret.Table[j].Current && Match(i, ret.Table[j].Current))
                    {
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
                }
            }
            foreach (var i in typeDef.Methods)  //Remaining
            {
                if (!i.IsVirtual)
                {
                    continue;
                }
                bool matched = false;
                for (int j = 0; j < ret.Table.Count; j++)
                {
                    if (Match(i, ret.Table[j].Current))
                    {
                        matched = true;
                        break;
                    }
                }
                if (!matched)
                {
                    ret.Table.Add(new VTableSlot()
                    {
                        Root    = i,
                        Current = i
                    });
                }
            }

            tbls[typeDef] = ret;
            return(ret);
        }
        public void ReplaceRoot(NameAnalyzer analyzer, MethodReference newRoot)
        {
            if (Root == newRoot || OpenRoot == newRoot) return;

            var renRef = (newRoot.Resolve() as IAnnotationProvider).Annotations[NameAnalyzer.RenRef] as List<IReference>;
            var root = (OpenRoot ?? Root).Resolve();
            var renId = (root as IAnnotationProvider).Annotations[NameAnalyzer.RenId] as Identifier?;
            if (analyzer.Assemblies.Contains(root.Module.Assembly))
                analyzer.Cr.Database.AddEntry(NameAnalyzer.DB_SRC, root.FullName, string.Format("Virtual override @ {0} => Not renamed", newRoot.FullName));
            (root as IAnnotationProvider).Annotations[NameAnalyzer.RenOk] = false;
            if (renRef != null && renId != null)
            {
                renRef.Add(new VirtualMethodReference(root));
            }
            Root = newRoot;
            OpenRoot = null;
        }
        public void ReplaceCurrent(NameAnalyzer analyzer, MethodReference newCurrent)
        {
            if (Current == newCurrent || OpenCurrent == newCurrent) return;

            MethodReference m = (((OpenCurrent ?? Current) ?? OpenRoot) ?? Root).Resolve();    //Interface method -> Empty slot
            if (m != null)
            {
                var renRef = (m as IAnnotationProvider).Annotations[NameAnalyzer.RenRef] as List<IReference>;
                var newCurrentDef = newCurrent.Resolve();
                var renId = (newCurrentDef as IAnnotationProvider).Annotations[NameAnalyzer.RenId] as Identifier?;
                if (analyzer.Assemblies.Contains(newCurrentDef.Module.Assembly))
                    analyzer.Cr.Database.AddEntry(NameAnalyzer.DB_SRC, newCurrent.FullName, string.Format("Virtual override @ {0} => Not renamed", m.FullName));
                (newCurrentDef as IAnnotationProvider).Annotations[NameAnalyzer.RenOk] = false;
                if (renRef != null)
                {
                    renRef.Add(new VirtualMethodReference(newCurrentDef));
                }
            }
            Current = newCurrent;
            OpenCurrent = null;
        }
        public static VTable GetVTable(NameAnalyzer analyzer, TypeDefinition typeDef, Dictionary<TypeDefinition, VTable> tbls)
        {
            if (tbls.ContainsKey(typeDef))
                return tbls[typeDef];

            //Partition II 10.3, 12.2

            VTable ret = new VTable() { TypeDef = typeDef };

            TypeDefinition baseType = null;
            if (typeDef.BaseType != null)
            {
                baseType = typeDef.BaseType.Resolve();
                if (baseType != null)
                {
                    ret.Table = new List<VTableSlot>(GetVTable(analyzer, baseType, tbls).Table);
                    if (typeDef.BaseType is GenericInstanceType)
                    {
                        GenericInstanceType genInst = typeDef.BaseType as GenericInstanceType;
                        for (int i = 0; i < ret.Table.Count; i++)
                        {
                            ret.Table[i] = ret.Table[i].Clone();
                            ret.Table[i].OpenCurrent = ret.Table[i].Current;
                            ret.Table[i].Current = Resolve(ret.Table[i].OpenCurrent, genInst);
                            ret.Table[i].OpenRoot = ret.Table[i].Root;
                            ret.Table[i].Root = Resolve(ret.Table[i].OpenRoot, genInst);
                        }
                    }
                }
                else
                    ret.Table = new List<VTableSlot>();
            }
            else
                ret.Table = new List<VTableSlot>();

            if (typeDef.HasInterfaces)          //Interface methods
            {
                foreach (var i in typeDef.Interfaces)
                {
                    if (baseType != null && baseType.Interfaces.Contains(i)) continue;

                    TypeDefinition iface = i.Resolve();
                    if (iface == null) continue;
                    GenericInstanceType genInst = i as GenericInstanceType;
                    foreach (var j in iface.Methods)
                    {
                        MethodReference ifaceMethod = j;
                        if (genInst != null)
                            ifaceMethod = Resolve(ifaceMethod, genInst);

                        VTableSlot slot = null;
                        for (int k = 0; k < ret.Table.Count; k++)
                            if (Match(ifaceMethod, ret.Table[k].Root))
                            {
                                slot = ret.Table[k];
                                break;
                            }
                        if (slot == null)
                        {
                            if (genInst != null)
                                ret.Table.Add(new VTableSlot()
                                {
                                    Root = ifaceMethod,
                                    OpenRoot = j,
                                    Current = null
                                });
                            else
                                ret.Table.Add(new VTableSlot()
                                {
                                    Root = ifaceMethod,
                                    Current = null
                                });
                        }
                        else
                        {
                            slot.ReplaceRoot(analyzer, j);
                        }
                    }
                }
            }

            foreach (var i in typeDef.Methods)  //Interface virtual newslot
            {
                if (!i.IsVirtual || !i.IsNewSlot) continue;
                for (int j = 0; j < ret.Table.Count; j++)
                    if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root))
                        ret.Table[j].ReplaceCurrent(analyzer, i);
            }
            foreach (var i in typeDef.Methods)  //Interface virtual
            {
                if (!i.IsVirtual) continue;
                for (int j = 0; j < ret.Table.Count; j++)
                    if (ret.Table[j].Current == null && Match(i, ret.Table[j].Root))
                        ret.Table[j].ReplaceCurrent(analyzer, i);
            }
            foreach (var i in typeDef.Methods)  //Base newslot
            {
                if (!i.IsVirtual || !i.IsNewSlot) continue;
                for (int j = 0; j < ret.Table.Count; j++)
                    if (Match(i, ret.Table[j].Current))
                    {
                        ret.Table[j].Root = i;
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
            }
            foreach (var i in typeDef.Methods)  //Base virtual
            {
                if (!i.IsVirtual) continue;
                for (int j = 0; j < ret.Table.Count; j++)
                    if (i != ret.Table[j].Current && Match(i, ret.Table[j].Current))
                    {
                        ret.Table[j].ReplaceCurrent(analyzer, i);
                    }
            }
            foreach (var i in typeDef.Methods)  //Remaining
            {
                if (!i.IsVirtual) continue;
                bool matched = false;
                for (int j = 0; j < ret.Table.Count; j++)
                    if (Match(i, ret.Table[j].Current))
                    {
                        matched = true;
                        break;
                    }
                if (!matched)
                    ret.Table.Add(new VTableSlot()
                    {
                        Root = i,
                        Current = i
                    });
            }

            tbls[typeDef] = ret;
            return ret;
        }