public IEnumerable <PossibleAssembly> ExtendFromStartNode(DeBruijnNode start)
        {
            //TODO: I believe this handles figure 8s and palindromes just fine, should verify though.

            //First go Right
            var rightNeighbors             = start.GetRightExtensionNodesWithOrientationMarkingEdgeAsVisited(false);
            List <PossibleAssembly> rights = new List <PossibleAssembly>();

            foreach (var direction in rightNeighbors)
            {
                PossibleAssembly pa = new PossibleAssembly(start, true);
                rights.AddRange(ExtendChain(pa, direction.Key, true, direction.Value));
            }
            List <PossibleAssembly> lefts = new List <PossibleAssembly>();
            var leftNeighbors             = start.GetLeftExtensionNodesWithOrientationMarkingEdgeAsVisited(false);

            foreach (var direction in leftNeighbors)
            {
                PossibleAssembly pa = new PossibleAssembly(start, false);
                lefts.AddRange(ExtendChain(pa, direction.Key, false, direction.Value));
            }
            //Now to combine a left and right chain
            if (lefts.Count > 0 && rights.Count > 0)
            {
                foreach (var right in rights)
                {
                    foreach (var left in lefts)
                    {
                        yield return(new PossibleAssembly(left, right));
                    }
                }
            }
            else if (lefts.Count > 0)
            {
                foreach (var left in lefts)
                {
                    yield return(left);
                }
            }
            else if (rights.Count > 0)
            {
                foreach (var right in rights)
                {
                    yield return(right);
                }
            }
        }
        private IEnumerable <PossibleAssembly> ExtendChain(PossibleAssembly currentPath, DeBruijnNode nextNeighbor, bool goingRight, bool sameOrientation)
        {
            byte nextSymbol = MetaNode.GetNextSymbol(nextNeighbor, KmerLength, !goingRight);

            currentPath.Add(nextNeighbor, nextSymbol);
            nextNeighbor.IsVisited = true;
            bool nextRight = !goingRight ^ sameOrientation;
            List <KeyValuePair <DeBruijnNode, bool> > nextNodes = nextRight ? nextNeighbor.GetRightExtensionNodesWithOrientationMarkingEdgeAsVisited() :
                                                                  nextNeighbor.GetLeftExtensionNodesWithOrientationMarkingEdgeAsVisited();
            DeBruijnNode next;

            //DeBruijnNode last = currentPath.constituentNodes[currentPath.constituentNodes.Count-1];
            //DeBruijnNode first=currentPath.constituentNodes[0];
            while (nextNodes.Count == 1)
            {
                var nextSet = nextNodes.First();
                next            = nextSet.Key;
                sameOrientation = nextSet.Value;
                nextRight       = (!nextRight) ^ sameOrientation;
                nextSymbol      = MetaNode.GetNextSymbol(next, KmerLength, !nextRight);
                //now check if we are in a circle or a loop at the end, these are very annoying situtations, basic criteria, can't leave
                //the same node the same way twice
                if (next.IsVisited && currentPath.constituentNodes.Contains(next))
                {
                    //okay, if we are equal to the first node or the last node, we can't leave or return the same way we came, otherwise we are done.
                    var excludedNextNodes = currentPath.GetPreviousWaysNodeWasLeft(next);
                    //how many neighbors dow we have in this group?
                    var temp = nextRight ? next.GetRightExtensionNodesWithOrientationMarkingEdgeAsVisited() : next.GetLeftExtensionNodesWithOrientationMarkingEdgeAsVisited();
                    temp = temp.Where(x => !excludedNextNodes.Contains(x.Key)).ToList();
                    //only one way to go
                    if (temp.Count == 1)
                    {
                        nextNodes = temp;
                        //currentPath.contigSequence.Add(nextSymbol);
                        currentPath.Add(next, nextSymbol);
                        next.IsVisited = true; //flag not actually used though
                    }
                    else if (temp.Count == 0)  //done
                    {
                        if (currentPath.constituentNodes[0] == next)
                        {
                            currentPath.CircularLoop = true;
                        }
                        yield return(currentPath);

                        //nextNodes.Clear();//we are done
                        yield break;
                    }
                    else //Extend path using all feasible options, then continue.
                    {
                        foreach (var neighbor in temp)
                        {
                            foreach (var v in ExtendChain(currentPath.Clone(), neighbor.Key, nextRight, neighbor.Value))
                            {
                                yield return(v);
                            }
                        }
                        //nextNodes.Clear();//done
                        yield break;
                    }
                }
                else
                {
                    //currentPath.contigSequence.Add(nextSymbol);
                    currentPath.Add(next, nextSymbol);
                    next.IsVisited = true;//flag not actually used though
                    nextNodes      = nextRight ? next.GetRightExtensionNodesWithOrientationMarkingEdgeAsVisited() : next.GetLeftExtensionNodesWithOrientationMarkingEdgeAsVisited();
                }
            }
            //If we have more than one node remaining, have to kick it off.
            if (nextNodes.Count > 1)
            {
                foreach (var neighbor in nextNodes)
                {
                    foreach (var v in ExtendChain(currentPath.Clone(), neighbor.Key, nextRight, neighbor.Value))
                    {
                        yield return(v);
                    }
                }
            }
            if (nextNodes.Count == 0)
            {
                yield return(currentPath);
            }
        }