private void FillAfferentGraph(string fullName, Dictionary <string, bool> cutPoints, AffectedGraph graph, MemberReference parent, int depth, TypeDefinition inheritedTypeContext, bool inVirtual, List <string> breadCrumbs, GenericContext genericContext, bool inSelf)
        {
            WriteWalkerDebug(fullName, depth);
            if (TryBreadCrumbsPrune(fullName, depth, breadCrumbs))
            {
                if (parent != null)
                {
                    WriteWalkerDebug("truncating but adding connection to " + fullName, depth);
                    graph.AddConnection(parent.GetCacheName(), fullName, false);
                }
                return;
            }
            breadCrumbs.Add(fullName);
            if (TryCutPointPrune(fullName, depth, cutPoints))
            {
                if (parent != null)
                {
                    WriteWalkerDebug("bread crumbs truncating but adding connection to " + fullName, depth);
                    graph.AddConnection(parent.GetCacheName(), fullName, false);
                }
                return;
            }

            var efferentEntry = _cache.TryGetEfferentCouplingNode(fullName);
            var afferentEntry = _cache.TryGetEfferentCouplingNode(fullName);
            MethodDefinition currentDefinition = null;

            if (efferentEntry != null)
            {
                TypeReference parentType = null;
                if (parent != null)
                {
                    parentType = parent.DeclaringType;
                }
                var definition = efferentEntry.MemberReference.DeclaringType.ThreadSafeResolve();
                if (TryInterfacePrune(fullName, depth, breadCrumbs, efferentEntry, parentType, definition))
                {
                    return;
                }
                if (TryInheritancePrune(fullName, depth, breadCrumbs, inVirtual, definition, inheritedTypeContext))
                {
                    return;
                }
                inheritedTypeContext = GetNewTypeContext(inheritedTypeContext, definition);
                currentDefinition    = efferentEntry.MemberReference as MethodDefinition;
                if (currentDefinition != null)
                {
                    if (currentDefinition.DeclaringType == null)
                    {
                    }
                    if (parent is FieldReference && currentDefinition.IsConstructor)
                    {
                        breadCrumbs.Remove(fullName);
                        return;
                    }
                }
            }
            var touse = afferentEntry ?? efferentEntry;

            WriteWalkerDebug("adding node " + fullName, depth);
            var newnode = GetGraphNode(fullName, touse, parent == null, false);

            graph.AddNode(newnode);
            if (parent != null)
            {
                graph.AddConnection(parent.GetCacheName(), newnode.FullName, false);
            }
            if (currentDefinition != null)
            {
                RecurseSynonyms(depth, cutPoints, inheritedTypeContext, currentDefinition, graph, breadCrumbs, genericContext);
            }
            RecurseAfferentCouplings(fullName, depth, cutPoints, inVirtual, inheritedTypeContext, graph, parent, breadCrumbs, genericContext);
            breadCrumbs.Remove(fullName);
        }
        private void GetEfferentGraph(string parent, string fullName, IDictionary <string, bool> cutOffs, List <ChangeContext> found, AffectedGraph graph, bool isRootNode, TypeDefinition originalContext)
        {
            var entry    = _cache.TryGetEfferentCouplingNode(fullName);
            var afferent = _cache.TryGetAfferentCouplingNode(fullName);

            if (isRootNode)
            {
                entry = entry ?? afferent;
                found.Add(new ChangeContext(fullName, null));
                graph.AddNode(GetGraphNode(fullName, entry, true, true));
                if (entry != null && entry.MemberReference != null)
                {
                    var refer = entry.MemberReference as MethodReference;
                    if (refer != null && _testStrategies.IsTest(refer))
                    {
                        return;
                    }
                }
            }
            //TODO Greg this hamstrings some stuff but should work better in most cases
            //I think we only really need statics past here but need to look it over a bit.
            return;

            WriteWalkerDebug("checking " + fullName, 0);
            if (entry == null)
            {
                WriteWalkerDebug("efferent entry is null", 0);
                if (afferent != null && afferent.MemberReference is MethodReference)
                {
                    return;                                                                  //Leaf node to a method call
                }
            }
            if (afferent == null)
            {
                WriteWalkerDebug("afferent entry is null", 0);
            }
            if (afferent != null)
            {
                var memref           = afferent.MemberReference as MethodReference;
                MethodDefinition def = null;
                if (memref != null)
                {
                    def = memref.ThreadSafeResolve();
                }
                if (!isRootNode && def != null)
                {
                    if (def.IsGetter)
                    {
                        return;
                    }
                    if (def.DeclaringType.IsInterface)
                    {
                        return;                                //don't recurse forward on interface calls
                    }
                    if (!def.HasThis)
                    {
                        return;
                    }
                }
                var reference = afferent.MemberReference as FieldReference; //Leaf node to a field reference
                if (reference != null)
                {
                    graph.AddNode(GetGraphNode(fullName, afferent, isRootNode, false));
                    if (parent != null)
                    {
                        graph.AddConnection(parent, fullName, true);
                    }

                    found.Add(new ChangeContext(fullName, originalContext));
                }
            }

            if (entry == null)
            {
                return;
            }
            graph.AddNode(GetGraphNode(fullName, entry, isRootNode, false));
            if (parent != null)
            {
                graph.AddConnection(parent, fullName, true);
            }
            foreach (var current in entry.Couplings)
            {
                if (cutOffs.ContainsKey(current.To))
                {
                    continue;
                }
                if (current.IgnoreWalk)
                {
                    continue;
                }
                if (current.ActualReference is MethodReference && !current.IsSelfCall)
                {
                    continue;
                }
                cutOffs.Add(current.To, true);
                GetEfferentGraph(fullName, current.To, cutOffs, found, graph, false, originalContext);
            }
        }