long AssemblyJobSsDeBruijn::combineTreesMidHelp(SeqNode* topNodeA, int kmerSize,
						SeqNode* branchA, SeqNode* branchB, int remainingKmer){
  char nucs[] = {'A','T','C','G'};
  long newNodeSum = 0;
  if (remainingKmer == 1){
    for (int n = 0; n < 4; ++n){
      DeBruijnNode* newNodeB = dynamic_cast<DeBruijnNode*>(branchB->getBranch(nucs[n]));
      if (newNodeB != 0){
	DeBruijnNode* newNodeA = dynamic_cast<DeBruijnNode*>(branchA->getBranch(nucs[n]));
	if (newNodeA == 0){
	  newNodeA = new DeBruijnNode(branchA,nucs[n]);
	  branchA->addBranch( newNodeA );
	  newNodeSum += 1;
	}
	newNodeA->addKmerScore( newNodeB->getKmerScore() );
	newNodeSum += combineTreesBottomHelp(topNodeA, kmerSize, newNodeA, newNodeB);
      }
    }
  } else {
    for (int n = 0; n < 4; ++n){
      SeqNode* newNodeB = branchB->getBranch(nucs[n]);
      if (newNodeB != 0){
	SeqNode* newNodeA = branchA->getBranch(nucs[n]);
	if (newNodeA == 0){
	  newNodeA = new NucNode(branchA,nucs[n]);
	  branchA->addBranch( newNodeA );
	}
	newNodeSum += combineTreesMidHelp(topNodeA, kmerSize, newNodeA, newNodeB, remainingKmer-1);
      }
    }
  }
  return newNodeSum;
}
ScoredSeq* AssemblyJobSsDeBruijn::makeSeqFromPath(DeBruijnNode* node5p, DeBruijnNode* node3p, long numNodes){
  long seqLen = _kmerSize + numNodes - 1;
  char* cSeq = new char[seqLen + 1];
  cSeq[seqLen] = '\0';
  float* scores = new float[seqLen];
  float* links = new float[seqLen-1];

  // do the initial kmer and any overlapping positions
  node5p->getKmer(cSeq,0);
  float firstScore = node5p->getKmerScore();
  for (int n = 0; n < _kmerSize; ++n){
    scores[n] = firstScore;
    if (n < _kmerSize - 1){ links[n] = firstScore; }
  }

  // fill in the rest
  DeBruijnNode* currentNode = node5p;
  DeBruijnNode* priorNode = 0;
  long pos5p = 0;
  long pos3p = _kmerSize - 1;
  while (currentNode != node3p){
    // increment
    pos5p++;
    pos3p++;
    priorNode = currentNode;
    currentNode = currentNode->best3pLink();
    // fill in values
    cSeq[pos3p] = currentNode->get3pNuc();
    scores[pos3p] = currentNode->getKmerScore();
    links[pos3p-1] = priorNode->get3pLinkScore( currentNode->get3pNuc() );
    if (links[pos5p-1] < currentNode->get5pLinkScore( cSeq[pos5p-1] )){
      links[pos5p-1] = currentNode->get5pLinkScore( cSeq[pos5p-1] );
    }
    for (long pos = pos5p; pos < pos3p; ++pos){
      if (scores[pos] < currentNode->getKmerScore()){ scores[pos] = currentNode->getKmerScore(); }
    }
  }

  ScoredSeq* novelSeq = new ScoredSeqShallow(true, cSeq, scores, links, seqLen);
  //ScoredSeq* novelSeq = ScoredSeq::getScoredSeq(cSeq, scores, links, seqLen);
  /*
  delete [] cSeq;
  delete [] scores;
  delete [] links;
  */
  return novelSeq;
}
void AssemblyJobSsDeBruijn::testTreeConstructionHelper(set<ScoredSeq*>* foundKmers, SeqNode* node, int stepsToBottom){
  if (stepsToBottom == 0){
    DeBruijnNode* dbNode = dynamic_cast<DeBruijnNode*>(node);
    foundKmers->insert( new ScoredSeqMonoScore(dbNode->getKmer(), dbNode->getKmerScore()) );
    //foundKmers->insert( ScoredSeq::getScoredSeq(dbNode->getKmer(), dbNode->getKmerScore()) );
  } else {
    char nucList[] = {'A','T','C','G'};
    for (int n = 0; n < 4; ++n){
      SeqNode* nextNode = node->getBranch( nucList[n] );
      if (nextNode != 0){ testTreeConstructionHelper( foundKmers, nextNode, stepsToBottom-1 ); }
    }
  }
}