static char rcsid[] = "$Id: 35cdc209a6ba8b9d3a837ebbbf15ab8460047a6b $";
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_MEMCPY
#define memcpy(d,s,n) bcopy((s),(d),(n))
#endif

#include "path.h"
#include "path-solve.h"
#include "path-eval.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "assert.h"

#include "genomebits_count.h"
#include "genomebits_indel.h"
#include "splice.h"
#include "indel.h"
#include "spliceends.h"

#include "intron.h"

#include "univdiagdef.h"
#include "junction.h"

#include "sedgesort.h"
#ifdef LARGE_GENOMES
#include "merge-uint8.h"
#include "uint8list.h"
#include "uint8table.h"
#else
#include "uintlist.h"
#endif

#include "repair.h"
#include "transcript-remap.h"


/* Cannot measure exon length since we run into the start or end of the read */
/* #define MIN_EXONLEN 20 */
#define MIN_INTRONLEN 9

#define MAX_DEPTH_MIDDLE 3
#define MAX_DEPTH_LOCAL 2
#define MAX_RECURSIVE_ENDS 2	/* Needs to be 2 or more, because the case of 1 is already checked */

#define MIN_SUPPORT_INDEL 6	/* Also defined in kmer-search.c */

#define PROB_SLOP 0.2


/* Creation and freeing of paths */
#ifdef DEBUG0
#define debug0(x) x
#else
#define debug0(x)
#endif

/* Decision on whether to consider path */
#ifdef DEBUG1
#define debug1(x) x
#else
#define debug1(x)
#endif

/* endpoints_acceptable_p */
#ifdef DEBUG2
#define debug2(x) x
#else
#define debug2(x)
#endif

/* qstart and qend resolve */
#ifdef DEBUG3
#define debug3(x) x
#else
#define debug3(x)
#endif

/* Path_nmatches */
#ifdef DEBUG7
#define debug7(x) x
#else
#define debug7(x)
#endif

/* Deletionpos */
#ifdef DEBUG6
#define debug6(x) x
#else
#define debug6(x)
#endif

/* Path_extend */
#ifdef DEBUG11
#define debug11(x) x
#else
#define debug11(x)
#endif

/* best_path_genome */
#ifdef DEBUG13
#define debug13(x) x
#else
#define debug13(x)
#endif

/* Path_fill_spliceindel */
#ifdef DEBUG14
#define debug14(x) x
#else
#define debug14(x)
#endif

/* Location of path */
#ifdef DEBUG20
#define debug20(x) x
#else
#define debug20(x)
#endif



static bool *circularp;

static Transcriptome_T transcriptome;
static Genomebits_T genomebits;
static Genomebits_T genomebits_alt;
static Univcoord_T genomelength;

static Localdb_T localdb;

static Chrpos_T min_intronlength;

/* Splicing */
static bool splicingp;
static bool novelsplicingp;

/* For splice plus indel */
/* static int max_splice_deletionlen = 3; */
/* static int max_splice_insertionlen = 3; */


#define T Path_T


/* Used with knownindels */
static T
attach_indel_qstart_simple (int adj, T path, int indel_pos,
			    Univcoord_T univdiagonal, int querylength, int try_sensedir,
			    bool plusp, int genestrand, int *mismatch_positions_alloc,
			    Knownsplicing_T knownsplicing, Spliceendsgen_T spliceendsgen,
			    Compress_T query_compress, char *queryptr,
			    Genomebits_T genomebits, Genomebits_T genomebits_alt,
			    Chrnum_T chrnum, Univcoord_T chroffset, bool novelsplicingp,
			    Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
			    Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath;
  Univcoord_T deletionpos;

  Univcoord_T distal_univdiagonal;
  int trimpos, nmismatches_to_trimpos, exon_origin;
  int found_sensedir;
  bool splice5p;
  Splicetype_T splicetype5;
  double ambig_prob_5;

  /* Subtract adj to get low diagonal for qstart, but add adj to get high diagonal for qend */
  distal_univdiagonal = univdiagonal - adj;

  /* Becauses splices are common, it is more likely that we have a
     splice distal to an indel than an indel distal to a splice */
  exon_origin = Path_exon_origin(path);
  debug13(printf("Calling Spliceends_qstart_trim with indel_pos %d\n",indel_pos));
  splice5p = Spliceends_qstart_trim(&trimpos,&nmismatches_to_trimpos,
				    &found_sensedir,&splicetype5,&ambig_prob_5,
				    knownsplicing,try_sensedir,
				    distal_univdiagonal,querylength,
				    /*pos3*/indel_pos,exon_origin,chrnum,chroffset,
				    plusp,genestrand,mismatch_positions_alloc,
				    spliceendsgen,query_compress,queryptr,
				    genomebits,genomebits_alt,novelsplicingp);
  debug13(printf("(1) Spliceends_qstart_trim returns trimpos %d and %d nmismatches, splice5 prob %f\n",
		 trimpos,nmismatches_to_trimpos,ambig_prob_5));

  if (trimpos == indel_pos) {
    debug13(printf("New indel does not have a good distal segment\n"));
    return (T) NULL;

  } else {
    newpath = Path_copy_5(path,splice5p,splicetype5,ambig_prob_5,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

    if (indel_pos == Intlist_head(newpath->endpoints)) {
      /* No change, so can keep nmismatches */
    } else if (indel_pos > Intlist_head(newpath->endpoints) && Intlist_head(newpath->nmismatches) == 0) {
      /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
      Intlist_head_set(newpath->endpoints,indel_pos);
    } else {
      /* Need to re-compute nmismatches */
      Intlist_head_set(newpath->endpoints,indel_pos);
      Intlist_head_set(newpath->nmismatches,-1); /* From previous endpoint to indel_pos */
      Intlist_head_set(newpath->ref_nmismatches,-1); /* From previous endpoint to indel_pos */
    }
    newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,trimpos
					  intlistpool_trace(__FILE__,__LINE__));

    newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_to_trimpos
					    intlistpool_trace(__FILE__,__LINE__)); /* from indel_pos to trimpos */
    newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_to_trimpos
						intlistpool_trace(__FILE__,__LINE__)); /* from indel_pos to trimpos */

    newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,distal_univdiagonal
						    univcoordlistpool_trace(__FILE__,__LINE__));

    if (adj < 0) {
      /* Start insertion */
      debug13(printf("Start insertion.  New diagonal is %u\n",distal_univdiagonal));
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_insertion(/*nindels*/-adj,pathpool)
					 listpool_trace(__FILE__,__LINE__));
    } else {
      /* Start deletion */
      debug13(printf("Start deletion.  New diagonal is %u\n",distal_univdiagonal));

      deletionpos = (univdiagonal - querylength) + indel_pos;
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_deletion(/*nindels*/adj,deletionpos,pathpool)
					 listpool_trace(__FILE__,__LINE__));
    }

    debug13(Path_print(newpath));
    debug13(printf("\n"));

    assert(newpath != path);
    return newpath;
  }
}


/* Uses parts of attach_unknown_qstart */
/* Returns a newpath without modifying or deleting path */
static T
attach_indel_qstart (T path, Univcoord_T low_univdiagonal, int low_qstart,
		     Univcoord_T chroffset, Univcoord_T chrhigh, int querylength, Indelinfo_T indelinfo,
		     Compress_T query_compress, bool plusp, int genestrand,
		     int max_insertionlen, int max_deletionlen,
		     Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		     Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath = NULL;
  Univcoord_T univdiagonal;
  int qend;
  int nindels, indel_pos;
  Univcoord_T deletionpos;
  int nmismatches_i, nmismatches_j, ref_nmismatches_i, ref_nmismatches_j;
#ifdef DEBUG13
  int qstart;
#endif
  
  /* Do not need to call Spliceends_qstart_trim, because
     Genomebits_indel_solve_low has already computed trimpos, provided
     as low_qstart */

  univdiagonal = Univcoordlist_head(path->univdiagonals);

  /* Assume that left+qend gives a coordinate within genome */
  qend = Intlist_second_value(path->endpoints) /*+ ninserts*/;

#ifdef DEBUG13
  if (path->junctions == NULL) {
    /* ninserts = 0; */
  } else {
    /* ninserts = Junction_ninserts(List_head(path->junctions)); */
  }

  qstart = Intlist_head(path->endpoints) /*+ ninserts*/;
  printf("Entering attach_unknown_qstart with low_univdiagonal %u, low_qstart %d,and univdiagonal %u %d..%d (diff %d)\n",
	 low_univdiagonal,low_qstart,univdiagonal,qstart,qend,univdiagonal - low_univdiagonal);
#endif

  if (low_univdiagonal > univdiagonal + max_insertionlen) {
    /* Impossible */
    debug13(printf("Impossible\n"));

  } else if (low_univdiagonal + low_qstart < chroffset + querylength) {
    debug13(printf("Extends beyond start of chromosome: low_univdiagonal %u - querylength %d + low_qstart %d vs chroffset %u\n",
		   low_univdiagonal,querylength,low_qstart,chroffset));

  } else if (low_univdiagonal > univdiagonal) {
    /* (A) Insertion */
    nindels = low_univdiagonal - univdiagonal;
    if ((indel_pos = Indel_resolve_middle_insertion(&nmismatches_i,&nmismatches_j,
						    &ref_nmismatches_i,&ref_nmismatches_j,
						    /*univdiagonal*/low_univdiagonal,/*indels*/+nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						    /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						    /*pos5*/low_qstart,/*pos3*/qend,querylength,
						    indelinfo,plusp,genestrand,
						    /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("(1) Insertion fails\n"));
      
    } else {
#if 0
      supporti = indel_pos - low_qstart;
      supportj = qend - (indel_pos + nindels);
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      }
#endif
      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
      debug13(printf("(3) attach_unknown_qstart is modifying path %p\n",newpath));
      Intlist_head_set(newpath->endpoints,indel_pos);
      newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					    intlistpool_trace(__FILE__,__LINE__));
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_insertion(nindels,pathpool)
					 listpool_trace(__FILE__,__LINE__));
	
      /* For qstart, push j first, then push i */
      Intlist_head_set(newpath->nmismatches,nmismatches_j);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
      newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
					      intlistpool_trace(__FILE__,__LINE__));
      newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						  intlistpool_trace(__FILE__,__LINE__));
	
      newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
						      univcoordlistpool_trace(__FILE__,__LINE__));
      debug13(printf("Insertion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		     low_qstart,qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
    }
    
  } else if (low_univdiagonal + max_deletionlen >= univdiagonal) {
    /* (B) Deletion (or short intron) */
    nindels = univdiagonal - low_univdiagonal;
    if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						   &ref_nmismatches_i,&ref_nmismatches_j,
						   /*univdiagonal_i*/low_univdiagonal,/*indels*/-nindels,chrhigh,
						   /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						   /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						   /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						   /*pos5*/low_qstart,/*pos3*/qend,querylength,
						   indelinfo,plusp,genestrand,
						   /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("Deletion or short intron fails\n"));
	  
    } else {
#if 0
      supporti = indel_pos - low_qstart;
      supportj = qend - indel_pos;
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      }
#endif
      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	    
      assert(nindels >= 0);
      deletionpos = (low_univdiagonal - querylength) + indel_pos;
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					 listpool_trace(__FILE__,__LINE__));
	

      debug13(printf("(4) attach_unknown_qstart is modifying path %p\n",newpath));
      Intlist_head_set(newpath->endpoints,indel_pos);
      newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					    intlistpool_trace(__FILE__,__LINE__));
	
      /* For qstart, push j first, then push i */
      Intlist_head_set(newpath->nmismatches,nmismatches_j);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
      newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
					      intlistpool_trace(__FILE__,__LINE__));
      newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						  intlistpool_trace(__FILE__,__LINE__));
      
      newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
						      univcoordlistpool_trace(__FILE__,__LINE__));
      debug13(printf("Deletion or short splice in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		     low_qstart,qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
    }
  }

  assert(newpath != path);
  return newpath;
}


/* Returns a newpath without modifying or deleting path */
static T
attach_splice_qstart (T path, int splice_qpos, int querylength,
		      bool plusp, int genestrand, int try_sensedir,
		      double medial_prob, double distal_prob,
		      Univcoord_T medial_univdiagonal, Univcoord_T distal_univdiagonal,
		      Chrnum_T chrnum, Univcoord_T chroffset,
		      Knownsplicing_T knownsplicing, Spliceendsgen_T spliceendsgen, int *mismatch_positions_alloc,
		      Compress_T query_compress, char *queryptr,
		      Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		      Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath;
  int trimpos, nmismatches_to_trimpos, exon_origin;
  int found_sensedir;
  bool splice5p;
  Splicetype_T splicetype5;
  double ambig_prob_5;
  Chrpos_T splice_distance;

  exon_origin = Path_exon_origin(path);
  debug13(printf("Calling Spliceends_qstart_trim with splice_qpos %d\n",splice_qpos));
  splice5p = Spliceends_qstart_trim(&trimpos,&nmismatches_to_trimpos,&found_sensedir,&splicetype5,&ambig_prob_5,
				    knownsplicing,try_sensedir,
				    distal_univdiagonal,querylength,
				    /*pos3*/splice_qpos,exon_origin,chrnum,chroffset,
				    plusp,genestrand,mismatch_positions_alloc,
				    spliceendsgen,query_compress,queryptr,
				    genomebits,genomebits_alt,novelsplicingp);
  debug13(printf("(2) Spliceends_qstart_trim returns trimpos %d and %d nmismatches, splice5 prob %f\n",
		 trimpos,nmismatches_to_trimpos,ambig_prob_5));

  if (trimpos == splice_qpos) {
    debug13(printf("New splice does not have a good distal segment\n"));
    return (T) NULL;

  } else {
    newpath = Path_copy_5(path,splice5p,splicetype5,ambig_prob_5,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

    debug13(printf("(1) attach_splice_qstart (splice) is modifying path %p\n",newpath));
    debug13(printf("Adding an intron on top of qstart diagonal with splice pos %d: %u to %u\n",
		   splice_qpos,medial_univdiagonal - chroffset,distal_univdiagonal - chroffset));
    debug13(printf("Before addition\n"));
    debug13(Path_print(newpath));
  
    if (splice_qpos == Intlist_head(newpath->endpoints)) {
      /* No change, so can keep nmismatches */
    } else if (splice_qpos > Intlist_head(newpath->endpoints) && Intlist_head(newpath->nmismatches) == 0) {
      /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
      Intlist_head_set(newpath->endpoints,splice_qpos);
    } else {
      /* Need to re-compute nmismatches */
      Intlist_head_set(newpath->endpoints,splice_qpos);
      Intlist_head_set(newpath->nmismatches,-1); /* From previous endpoint to splice_qpos */
      Intlist_head_set(newpath->ref_nmismatches,-1); /* From previous endpoint to splice_qpos */
    }
    newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,trimpos
					  intlistpool_trace(__FILE__,__LINE__));

    newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_to_trimpos
					    intlistpool_trace(__FILE__,__LINE__)); /* from splice_qpos to trimpos */
    newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_to_trimpos
						intlistpool_trace(__FILE__,__LINE__)); /* from splice_qpos to trimpos */
	  
    newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,distal_univdiagonal
						    univcoordlistpool_trace(__FILE__,__LINE__));

    splice_distance = (Chrpos_T) (medial_univdiagonal - distal_univdiagonal);
    if (plusp) {
      if (found_sensedir == SENSE_FORWARD) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									/*donor_prob*/distal_prob,/*acceptor_prob*/medial_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else if (found_sensedir == SENSE_ANTI) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									/*donor_prob*/medial_prob,/*acceptor_prob*/distal_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else {
	fprintf(stderr,"Unexpected sensedir %d\n",found_sensedir);
	abort();
      }
    } else {
      if (found_sensedir == SENSE_ANTI) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									/*donor_prob*/distal_prob,/*acceptor_prob*/medial_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else if (found_sensedir == SENSE_FORWARD) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									/*donor_prob*/medial_prob,/*acceptor_prob*/distal_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else {
	fprintf(stderr,"Unexpected sensedir %d\n",found_sensedir);
	abort();
      }
    }
	  
    newpath->splice5p = false;
    newpath->splicetype5 = NO_SPLICE;
    newpath->ambig_prob_5 = 0.0;
  
    debug13(printf("After addition\n"));
    debug13(Path_print(newpath));
  
    assert(newpath != path);
    return newpath;
  }
}


/* Adds a diagonal to the start of a path, as found by
   compute_qstart_local.  Calls attach_unknown_qstart to modify the path,
   potentially leading to multiple paths */
static List_T
multiadd_splice_qstarts (T path, Univcoord_T univdiagonal,
			 int common_splice_qpos, double common_splice_prob,
			 Univcoord_T *distal_splice_positions, int *distal_nmismatches,
			 double *distal_probs, int npartners,
			 Chrnum_T chrnum, Univcoord_T chroffset, int querylength,
			 Compress_T query_compress, char *queryptr, bool plusp, int genestrand,
			 Knownsplicing_T knownsplicing,
			 Spliceendsgen_T spliceendsgen, int *mismatch_positions_alloc,
			 Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
			 Listpool_T listpool, Hitlistpool_T hitlistpool, Pathpool_T pathpool,
			 Vectorpool_T vectorpool, int found_sensedir) {
  T newpath;
  Univcoord_T distal_univdiagonal;

  debug13(printf("Entered multiadd_splice_qstarts with %d partners at univdiagonal %u, common_splice_qpos %d.  Current path: ",
		 npartners,univdiagonal,common_splice_qpos));
  debug13(Path_print(path));
  debug13(printf("\n"));

  if (npartners == 1) {
    assert(distal_splice_positions[0] != 0);
    distal_univdiagonal = distal_splice_positions[0] - common_splice_qpos + querylength;
    if (distal_univdiagonal == univdiagonal) {
      /* Not a splice.  Not sure whether to continue the alignment */
#if 0
      debug13(printf("Continuing the alignment to the start\n"));
      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
      Intlist_head_set(newpath->endpoints,0);
      Intlist_head_set(newpath->nmismatches,-1);
      Intlist_head_set(newpath->ref_nmismatches,-1);

      debug13(Path_print(newpath));
      return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(newpath)
			  hitlistpool_trace(__FILE__,__LINE__));
#else
      return (List_T) NULL;
#endif

    } else if ((newpath = attach_splice_qstart(path,common_splice_qpos,querylength,plusp,genestrand,found_sensedir,
					       /*medial_prob*/common_splice_prob,/*distal_prob*/distal_probs[0],
					       /*medial_univdiagonal*/univdiagonal,distal_univdiagonal,
#if 0
					       distal_nmismatches[0],/*distal_ref_nmismatches*/distal_nmismatches[0],
#endif
					       chrnum,chroffset,knownsplicing,
					       spliceendsgen,mismatch_positions_alloc,query_compress,queryptr,
					       intlistpool,univcoordlistpool,listpool,pathpool,vectorpool)) == NULL) {
      return (List_T) NULL;
    } else {
      assert(newpath != path);
      return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(newpath)
			  hitlistpool_trace(__FILE__,__LINE__));
    }

  } else if (0) {
    /* TODO: Need an indicator that we did not reach to the end.  Then store each path separately */

  } else {
    /* Extends to the start, so create an alt substring */
    debug13(printf("Creating an alt substring\n"));
    newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
    Intlist_head_set(newpath->endpoints,common_splice_qpos);
    Intlist_head_set(newpath->nmismatches,-1);
    Intlist_head_set(newpath->ref_nmismatches,-1);

    debug13(printf("Combining qstart alts for path:\n"));
    debug13(Path_print(newpath));

    newpath->qstart_alts = Altsplice_new(/*distal_length*/common_splice_qpos,/*medial_prob*/common_splice_prob,
					 distal_splice_positions,distal_nmismatches,distal_probs,npartners,
					 pathpool,vectorpool);

#if 0
    newpath->endpoints = Intlistpool_pop(newpath->endpoints,&ignore_int
					 intlistpool_trace(__FILE__,__LINE__));
    newpath->junctions = Listpool_pop(newpath->junctions,(void **) &junction
				      listpool_trace(__FILE__,__LINE__));
    Junction_free(&junction,pathpool);
    newpath->nmismatches = Intlistpool_pop(newpath->nmismatches,&ignore_int
					   intlistpool_trace(__FILE__,__LINE__));
    newpath->ref_nmismatches = Intlistpool_pop(newpath->ref_nmismatches,&ignore_int
					       intlistpool_trace(__FILE__,__LINE__));
    newpath->univdiagonals = Univcoordlistpool_pop(newpath->univdiagonals,&ignore_univcoord
						   univcoordlistpool_trace(__FILE__,__LINE__));
#endif

    debug13(printf("(2) Resulting path: "));
    debug13(Path_print(newpath));
    debug13(printf("add_qstart_local is returning path %p as newpaths\n",newpath));

    assert(newpath != path);
    return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(newpath)
			hitlistpool_trace(__FILE__,__LINE__));
  }
}


/* Implements the addition of a diagonal to the start of a path.
   Returns a Path_T object, or NULL if the diagonal cannot
   be attached.  All Path_T objects are copies of the original path */
/* Assume that left+low_qstart and left+low_qend give coordinates within genome */

/* Returns newpath, which is different from path */
static T
attach_unknown_qstart (T path, Univcoord_T low_univdiagonal, int low_qstart,
		       Univcoord_T chroffset, Univcoord_T chrhigh, int querylength,
		       Indelinfo_T indelinfo, Spliceinfo_T spliceinfo, Knownsplicing_T knownsplicing,
		       Compress_T query_compress, bool plusp, int genestrand,
		       int max_insertionlen, int max_deletionlen,
		       Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		       Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
		       Vectorpool_T vectorpool, int try_sensedir, bool salvagep) {
  T newpath = NULL;
  Univcoord_T univdiagonal, low_left;
  int qend;
  int nindels, indel_pos, splice_qpos, splice_qpos_i, splice_qpos_j;
  Univcoord_T middle_univdiagonal, deletionpos;
  Chrpos_T splice_distance, splice_distance_i, splice_distance_j;
  double donor_prob, acceptor_prob;
  int supporti, supportj;
  int nmismatches_i, nmismatches_j, ref_nmismatches_i, ref_nmismatches_j, 
    nmismatches, ref_nmismatches, nmismatches_middle, ref_nmismatches_middle;
#ifdef DEBUG13
  int qstart;
#endif
  
  int nmismatches_indel, ref_nmismatches_indel;

  if (low_univdiagonal < (Univcoord_T) (querylength - low_qstart)) {
    /* low segment is before the beginning of the genome */
    return (T) NULL;
  } else { 
    univdiagonal = Univcoordlist_head(path->univdiagonals);
  }

  /* Assume that left+qend gives a coordinate within genome */
  qend = Intlist_second_value(path->endpoints) /*+ ninserts*/;

#ifdef DEBUG13
  if (path->junctions == NULL) {
    /* ninserts = 0; */
  } else {
    /* ninserts = Junction_ninserts(List_head(path->junctions)); */
  }

  qstart = Intlist_head(path->endpoints) /*+ ninserts*/;
  printf("Entering attach_unknown_qstart with try_sensedir %d, low_univdiagonal %u and univdiagonal %u %d..%d (diff %d)\n",
	 try_sensedir,low_univdiagonal - chroffset,univdiagonal - chroffset,qstart,qend,univdiagonal - low_univdiagonal);
#endif

  if (low_qstart >= qend) {
    debug13(printf("Does not add to start of path: low_qstart %d >= qend %d\n",low_qstart,qend));

  } else if (low_univdiagonal + low_qstart < chroffset + querylength) {
    debug13(printf("Extends beyond start of chromosome: low_univdiagonal %u - querylength %d + low_qstart %u vs chroffset %u\n",
		   low_univdiagonal,querylength,low_qstart,chroffset));

  } else if (low_univdiagonal == univdiagonal) {
    if (low_qstart >= Intlist_head(path->endpoints)) {
      debug13(printf("Mismatch fails, since new endpoint %d >= old endpoint %d\n",low_qstart,Intlist_head(path->endpoints)));
    } else {
      /* Mismatch: Revise the endpoint */
      debug13(printf("Mismatch extends from %d to %d\n",Intlist_head(path->endpoints),low_qstart));
      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
      
      /* Determine nmismatches */
      nmismatches = Genomebits_count_mismatches_substring(&ref_nmismatches,genomebits,genomebits_alt,query_compress,
							  univdiagonal,querylength,/*pos5*/low_qstart,/*pos3*/qend,
							  plusp,genestrand);
      /* debug13(printf("Counting mismatches from %d to %d => %d (%d ref)\n",
	 low_qstart,qend,nmismatches,ref_nmismatches)); */

      debug13(printf("(2) attach_unknown_qstart is modifying path %p\n",newpath));
      Intlist_head_set(newpath->nmismatches,nmismatches);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches);
      Intlist_head_set(newpath->endpoints,low_qstart);
    }
    
  } else if (low_univdiagonal > univdiagonal + max_insertionlen) {
    /* Impossible */
    debug13(printf("Impossible\n"));

  } else if (low_univdiagonal > univdiagonal) {
    /* (A) Insertion */
    nindels = low_univdiagonal - univdiagonal;
    if ((indel_pos = Indel_resolve_middle_insertion(&nmismatches_i,&nmismatches_j,
						    &ref_nmismatches_i,&ref_nmismatches_j,
						    /*univdiagonal*/low_univdiagonal,/*indels*/+nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						    /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						    /*pos5*/low_qstart,/*pos3*/qend,querylength,
						    indelinfo,plusp,genestrand,
						    /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("(2) Insertion fails\n"));
      
    } else {
      supporti = indel_pos - low_qstart;
      supportj = qend - (indel_pos + nindels);
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			      intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
	debug13(printf("(3) attach_unknown_qstart is modifying path %p\n",newpath));
	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_insertion(nindels,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	debug13(printf("Insertion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		       low_qstart,qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
      }
    }
    
  } else if (low_univdiagonal + max_deletionlen >= univdiagonal) {
    /* (B) Deletion (or short intron) */
    nindels = univdiagonal - low_univdiagonal;
    if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						   &ref_nmismatches_i,&ref_nmismatches_j,
						   /*univdiagonal_i*/low_univdiagonal,/*indels*/-nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						   /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						   /*pos5*/low_qstart,/*pos3*/qend,querylength,
						   indelinfo,plusp,genestrand,
						   /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("Deletion or short intron fails\n"));
	  
    } else {
      supporti = indel_pos - low_qstart;
      supportj = qend - indel_pos;
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			      intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	    
	assert(nindels >= 0);
	deletionpos = (low_univdiagonal - querylength) + indel_pos;
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	      
	debug13(printf("(4) attach_unknown_qstart is modifying path %p\n",newpath));
	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	debug13(printf("Deletion or short splice in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		       low_qstart,qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
      }
    }

#ifdef DISALLOW_CIRCULAR_SPLICING
  } else if (circularp[chrnum] == true) {
    /* No splicing on circular chromosomes */
    debug13(printf("No splicing on circular chromosomes\n"));
#endif

  } else {
    /* (C) Splice with possible indel */
    low_left = low_univdiagonal - (Univcoord_T) querylength;
    /* left = univdiagonal - (Univcoord_T) querylength; */

    /* Previously filled spliceinfo with knownsplicing information
       on donors and antiacceptors for segmenti and segmentj, now
       done in Splice_resolve */
    
    if (try_sensedir == SENSE_FORWARD) {
      /* (C1) Sense */
      /* low_left = low_univdiagonal - querylength; -- Combined above */
      /* left = univdiagonal - querylength; -- Combined above */

      debug13(printf("BEFORE call to Splice_resolve, %d..%d\n",low_qstart,qend));
      debug13(Path_print(path));

      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					/*univdiagonal_i*/low_univdiagonal,/*univdiagonal_j*/univdiagonal,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/low_qstart,/*pos3*/qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/true,
					genestrand,max_insertionlen,max_deletionlen,
					salvagep,/*check_support_p*/true)) < 0) {
	if (middle_univdiagonal != 0) {
	  debug13(printf("Splice_resolve (qstart, sense): found a middle exon\n"));
	  splice_distance_j = univdiagonal - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - low_univdiagonal;
	  
	  debug13(printf("(6) attach_unknown_qstart is modifying path %p\n",newpath));
	  Intlist_head_set(newpath->endpoints,splice_qpos_j);
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos_i
						intlistpool_trace(__FILE__,__LINE__));
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
						intlistpool_trace(__FILE__,__LINE__));
	  
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_j,SENSE_FORWARD,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_i,SENSE_FORWARD,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	  
	  /* For qstart, push j first, then push i */
	  Intlist_head_set(newpath->nmismatches,nmismatches_j);
	  Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_middle
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_middle
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						      intlistpool_trace(__FILE__,__LINE__));
	  
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  
	} else {
	  debug13(printf("Splice_resolve (qstart, sense): fails\n"));
	  
#if 0
	  /* Put in a temporary junction, to be fixed later if it is worth it */
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
						intlistpool_trace(__FILE__,__LINE__));
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) Junction_new_unsolved(pathpool)
					     listpool_trace(__FILE__,__LINE__));
#else
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) JUNCTION_UNSOLVED
					     listpool_trace(__FILE__,__LINE__));
#endif

	  Intlist_head_set(newpath->nmismatches,-1);
	  Intlist_head_set(newpath->ref_nmismatches,-1);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,-1
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,-1
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  debug13(printf("attach_unknown_qstart is returning path %p with an unsolved junction\n",newpath));
#endif
#if 0
	  /* Already in qstart direction */
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) newpath
					   hitlistpool_trace(__FILE__,__LINE__));
#else
	  Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
#endif
	  newpath = (T) NULL;
	}

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = univdiagonal - low_univdiagonal;
	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else if (splice_qpos < indel_pos) {
	/* Push indel (based on left) then splice.  splice is distal, indel is medial */
	middle_univdiagonal = univdiagonal - nindels; /* nindels = univdiagonal - middle_univdiagonal */
	splice_distance = middle_univdiagonal - low_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): %d indels at %d, mismatches %d, then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,nmismatches_indel,
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));

	/* Indel first */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = low_left + splice_distance + indel_pos; /* qstart; add splice_distance if indel first */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on low_univdiagonal).  indel is distal, splice is medial */
	middle_univdiagonal = low_univdiagonal + nindels; /* nindels = middle_univdiagonal - low_univdiagonal */
	splice_distance = univdiagonal - middle_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d, nmismatches %d\n",
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos,nmismatches_indel));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,indel_pos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = low_left + indel_pos; /* qstart; do not add splice_distance if indel second */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
      }

      debug13(printf("AFTER call to Splice_resolve\n"));
      debug13(Path_print(newpath));
      
    } else {
      /* (C2) Antisense */
      /* low_left = low_univdiagonal - querylength; -- Computed above */
      /* left = univdiagonal - querylength; -- Computed above */

      debug13(printf("BEFORE call to Splice_resolve, %d..%d\n",low_qstart,qend));
      debug13(Path_print(path));

      newpath = Path_copy_5(path,/*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					/*univdiagonal_i*/low_univdiagonal,/*univdiagonal_j*/univdiagonal,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/low_qstart,/*pos3*/qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/false,
					genestrand,max_insertionlen,max_deletionlen,
					salvagep,/*check_support_p*/true)) < 0) {
	debug13(printf("(7) attach_unknown_qstart is modifying path %p\n",newpath));

	if (middle_univdiagonal != 0) {
	  debug13(printf("Splice_resolve (qstart, antisense): found a middle exon\n"));
	  splice_distance_j = univdiagonal - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - low_univdiagonal;
	
	  debug13(printf("(8) attach_unknown_qstart is modifying path %p\n",newpath));
	  Intlist_head_set(newpath->endpoints,splice_qpos_j);
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos_i
						intlistpool_trace(__FILE__,__LINE__));
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
						intlistpool_trace(__FILE__,__LINE__));
	
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_j,SENSE_ANTI,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_i,SENSE_ANTI,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	
	  /* For qstart, push j first, then push i */
	  Intlist_head_set(newpath->nmismatches,nmismatches_j);
	  Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_middle
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_middle
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						      intlistpool_trace(__FILE__,__LINE__));
	
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	
	  debug13(Path_print(newpath));

	} else {
	  debug13(printf("Splice_resolve (qstart, antisense): fails\n"));
#if 0
	  /* Put in a temporary junction, to be fixed later if it is worth it */
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
						intlistpool_trace(__FILE__,__LINE__));
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) Junction_new_unsolved(pathpool)
					     listpool_trace(__FILE__,__LINE__));
#else
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) JUNCTION_UNSOLVED
					     listpool_trace(__FILE__,__LINE__));
#endif

	  Intlist_head_set(newpath->nmismatches,-1);
	  Intlist_head_set(newpath->ref_nmismatches,-1);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,-1
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,-1
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  debug13(printf("attach_unknown_qstart is returning a path %p with an unsolved junction\n",newpath));
#endif

	  /* Already in qstart direction */
#if 0
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) newpath
					   hitlistpool_trace(__FILE__,__LINE__));
#else
	  Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
#endif
	  newpath = (T) NULL;
	}

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = univdiagonal - low_univdiagonal;
	debug13(printf("Splice_resolve (qstart, antisense): splice_qpos in range %d..%d is at %d with distance %u, nmismatches %d+%d, and probs %f and %f\n",
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));

	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else if (splice_qpos < indel_pos) {
	/* Push indel (based on left) then splice.  splice is distal, indel is medial */
	middle_univdiagonal = univdiagonal - nindels; /* nindels = univdiagonal - middle_univdiagonal */
	splice_distance = middle_univdiagonal - low_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): %d indels at %d, nmismatches %d, then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,nmismatches_indel,
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));

	/* Indel first */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = low_left + splice_distance + indel_pos; /* qstart; add splice_distance if indel first */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* For qstart, push j first, then push i */
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on low_univdiagonal).  indel is distal, splice is medial */
	middle_univdiagonal = low_univdiagonal + nindels; /* nindels = middle_univdiagonal - low_univdiagonal */
	splice_distance = univdiagonal - middle_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d, nmismatches %d\n",
		       low_qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos,nmismatches_indel));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,indel_pos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,low_qstart
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = low_left + indel_pos; /* qstart; do not add splice_distance if indel second */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	Intlist_head_set(newpath->nmismatches,nmismatches_j);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_j);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_i
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_i
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,low_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
      }

      debug13(printf("AFTER call to Splice_resolve\n"));
      debug13(Path_print(newpath));      
    }
  }

  debug13(printf("attach_unknown_qstart is returning newpath %p\n",newpath));

  assert(newpath != path);
  return newpath;
}


#if 0
static void
check_for_ascending_values (Univcoord_T *diagonals, int ndiagonals) {
  int i;

  for (i = 0; i < ndiagonals - 1; i++) {
    if (diagonals[i+1] < diagonals[i]) {
      /* abort(); */
    }
  }
  return;
}
#endif


/* Used with knownindels */
static T
attach_indel_qend_simple (int adj, T path, int indel_pos,
			  Univcoord_T univdiagonal, int querylength, int try_sensedir,
			  bool plusp, int genestrand, int *mismatch_positions_alloc,
			  Knownsplicing_T knownsplicing, Spliceendsgen_T spliceendsgen,
			  Compress_T query_compress, char *queryptr,
			  Genomebits_T genomebits, Genomebits_T genomebits_alt,
			  Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh, bool novelsplicingp,
			  Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
			  Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath;
  Univcoord_T deletionpos;

  Univcoord_T distal_univdiagonal;
  int trimpos, nmismatches_to_trimpos, exon_origin;
  int found_sensedir;
  bool splice3p;
  Splicetype_T splicetype3;
  double ambig_prob_3;

  /* Subtract adj to get low diagonal for qstart, but add adj to get high diagonal for qend */
  distal_univdiagonal = univdiagonal + adj;

  /* Becauses splices are common, it is more likely that we have a
     splice distal to an indel than an indel distal to a splice */
  exon_origin = Path_exon_origin(path);
  debug13(printf("Calling Spliceends_qend_trim with indel_pos %d\n",indel_pos));
  splice3p = Spliceends_qend_trim(&trimpos,&nmismatches_to_trimpos,
				  &found_sensedir,&splicetype3,&ambig_prob_3,
				  knownsplicing,try_sensedir,
				  distal_univdiagonal,querylength,
				  /*pos5*/indel_pos,exon_origin,chrnum,chroffset,chrhigh,
				  plusp,genestrand,mismatch_positions_alloc,
				  spliceendsgen,query_compress,queryptr,
				  genomebits,genomebits_alt,novelsplicingp);
  debug13(printf("(1) Spliceends_qend_trim returns trimpos %d and %d nmismatches, splice3 prob %f\n",
		 trimpos,nmismatches_to_trimpos,ambig_prob_3));

  if (trimpos == indel_pos) {
    debug13(printf("New indel does not have a good distal segment\n"));
    return (T) NULL;

  } else {
    newpath = Path_copy_3(path,splice3p,splicetype3,ambig_prob_3,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

    if (indel_pos == Intlist_head(newpath->endpoints)) {
      /* No change, so can keep nmismatches */
    } else if (indel_pos > Intlist_head(newpath->endpoints) && Intlist_head(newpath->nmismatches) == 0) {
      /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
      Intlist_head_set(newpath->endpoints,indel_pos);
    } else {
      /* Need to re-compute nmismatches */
      Intlist_head_set(newpath->endpoints,indel_pos);
      Intlist_head_set(newpath->nmismatches,-1); /* From previous endpoint to indel_pos */
      Intlist_head_set(newpath->ref_nmismatches,-1); /* From previous endpoint to indel_pos */
    }
    newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,trimpos
					  intlistpool_trace(__FILE__,__LINE__));

    newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_to_trimpos
					    intlistpool_trace(__FILE__,__LINE__)); /* From indel_pos to trimpos */
    newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_to_trimpos
						intlistpool_trace(__FILE__,__LINE__));/* From indel_pos to trimpos */

    newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,distal_univdiagonal
						    univcoordlistpool_trace(__FILE__,__LINE__));


    /* Subtract adj to get low diagonal, but add adj to get high diagonal */
    /* For qend, push i first, then push j.  For qend, add adj. */
    if (adj < 0) {
      /* End insertion */
      debug13(printf("End insertion.  New diagonal is %u\n",distal_univdiagonal));
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_insertion(/*nindels*/-adj,pathpool)
					 listpool_trace(__FILE__,__LINE__));
    } else {
      /* End deletion */
      debug13(printf("End deletion.  New diagonal is %u\n",distal_univdiagonal));
      deletionpos = (univdiagonal - querylength) + indel_pos;
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_deletion(/*nindels*/adj,deletionpos,pathpool)
					 listpool_trace(__FILE__,__LINE__));
    }

    debug13(Path_print(newpath));
    debug13(printf("\n"));

    assert(newpath != path);
    return newpath;
  }
}



/* Uses code from attach_unknown_qend */
static T
attach_indel_qend (T path, Univcoord_T high_univdiagonal, int high_qend,
		   Univcoord_T chrhigh, int querylength, Indelinfo_T indelinfo,
		   Compress_T query_compress, bool plusp, int genestrand,
		   int max_insertionlen, int max_deletionlen,
		   Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		   Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath = NULL;
  Univcoord_T univdiagonal;
  int qstart, ninserts;
  int nindels, indel_pos;
  Univcoord_T deletionpos;
  int nmismatches_i, nmismatches_j, ref_nmismatches_i, ref_nmismatches_j;
#ifdef DEBUG13
  int qend;
#endif


  /* Do not need to call Spliceends_qend_trim, because
     Genomebits_indel_solve_high has already computed trimpos,
     provided as high_qend*/

  univdiagonal = Univcoordlist_head(path->univdiagonals);

#if 0
  ninserts = Junction_total_ninserts(path->junctions);
#else
  if (path->junctions == NULL) {
    ninserts = 0;
  } else {
    ninserts = Junction_ninserts(List_head(path->junctions));
  }
#endif

  /* Assume that left+qstart gives a coordinate within genome */
  qstart = Intlist_second_value(path->endpoints) + ninserts;

#ifdef DEBUG13
  qend = Intlist_head(path->endpoints) /*+ ninserts*/;
  printf("Entering attach_indel_qend with univdiagonal %u %d..%d and high_univdiagonal %u, high_qend %d (diff %d)\n",
	 univdiagonal,qstart,qend,high_univdiagonal,high_qend,high_univdiagonal - univdiagonal);
#endif

  if (high_univdiagonal + max_insertionlen < univdiagonal) {
    /* Impossible */
    debug13(printf("Impossible\n"));

  } else if (high_univdiagonal + high_qend >= chrhigh + querylength) {
    debug13(printf("Extends beyond end of chromosome: high_univdiagonal %u - querylength %d + high_qend %d vs chrhigh %u\n",
		   high_univdiagonal,querylength,high_qend,chrhigh));

  } else if (high_univdiagonal < univdiagonal) {
    /* (A) Insertion */
    nindels = univdiagonal - high_univdiagonal;
    if ((indel_pos = Indel_resolve_middle_insertion(&nmismatches_i,&nmismatches_j,
						    &ref_nmismatches_i,&ref_nmismatches_j,
						    univdiagonal,/*indels*/+nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						    /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						    /*pos5*/qstart,/*pos3*/high_qend,querylength,
						    indelinfo,plusp,genestrand,
						    /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("(3) Insertion fails\n"));

    } else {
#if 0
      supporti = indel_pos - qstart;
      supportj = high_qend - (indel_pos + nindels);
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      }
#endif
      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
      debug13(printf("(3) attach_indel_qend is modifying path %p\n",newpath));
      Intlist_head_set(newpath->endpoints,indel_pos);
      newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					    intlistpool_trace(__FILE__,__LINE__));
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_insertion(nindels,pathpool)
					 listpool_trace(__FILE__,__LINE__));
	
      /* For qend, push i first, then push j */
      Intlist_head_set(newpath->nmismatches,nmismatches_i);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
      newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
					      intlistpool_trace(__FILE__,__LINE__));
      newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_j
						  intlistpool_trace(__FILE__,__LINE__));
	
      newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
						      univcoordlistpool_trace(__FILE__,__LINE__));
      debug13(printf("Insertion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		     qstart,high_qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
	
      debug13(Path_print(newpath));
    }

  } else if (high_univdiagonal <= univdiagonal + max_deletionlen) {
    /* (B) Deletion (or short intron) */
    nindels = high_univdiagonal - univdiagonal;
    if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						   &ref_nmismatches_i,&ref_nmismatches_j,
						   /*univdiagonal_i*/univdiagonal,/*indels*/-nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						   /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						   /*pos5*/qstart,/*pos3*/high_qend,querylength,
						   indelinfo,plusp,genestrand,
						   /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("Deletion or short intron fails\n"));
      
    } else {
#if 0
      supporti = indel_pos - qstart;
      supportj = high_qend - indel_pos;
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      }
#endif

      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
      assert(nindels >= 0);
      deletionpos = (univdiagonal - querylength) + indel_pos;
      newpath->junctions = Listpool_push(newpath->junctions,listpool,
					 (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					 listpool_trace(__FILE__,__LINE__));
	
      debug13(printf("(4) attach_indel_qend is modifying path %p\n",newpath));
      Intlist_head_set(newpath->endpoints,indel_pos);
      newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					    intlistpool_trace(__FILE__,__LINE__));
	  
      /* For qend, push i first, then push j */
      Intlist_head_set(newpath->nmismatches,nmismatches_i);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
      newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
					      intlistpool_trace(__FILE__,__LINE__));
      newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_j
						  intlistpool_trace(__FILE__,__LINE__));
	
      newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
						      univcoordlistpool_trace(__FILE__,__LINE__));
      debug13(printf("Deletion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		     qstart,high_qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
	
      debug13(Path_print(newpath));
    }
  }

  assert(newpath != path);
  return newpath;
}


/* Returns a new path without modifying deleting path */
static T
attach_splice_qend (T path, int splice_qpos, int querylength,
		    bool plusp, int genestrand, int try_sensedir,
		    double medial_prob, double distal_prob,
		    Univcoord_T medial_univdiagonal, Univcoord_T distal_univdiagonal,
		    Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
		    Knownsplicing_T knownsplicing, Spliceendsgen_T spliceendsgen, int *mismatch_positions_alloc,
		    Compress_T query_compress, char *queryptr,
		    Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		    Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool) {
  T newpath;
  int trimpos, nmismatches_to_trimpos, exon_origin;
  int found_sensedir;
  bool splice3p;
  Splicetype_T splicetype3;
  double ambig_prob_3;
  Chrpos_T splice_distance;

  exon_origin = Path_exon_origin(path);
  debug13(printf("Calling Spliceends_qend_trim with splice_qpos %d\n",splice_qpos));
  splice3p = Spliceends_qend_trim(&trimpos,&nmismatches_to_trimpos,
				  &found_sensedir,&splicetype3,&ambig_prob_3,
				  knownsplicing,try_sensedir,
				  distal_univdiagonal,querylength,
				  /*pos5*/splice_qpos,exon_origin,chrnum,chroffset,chrhigh,
				  plusp,genestrand,mismatch_positions_alloc,
				  spliceendsgen,query_compress,queryptr,
				  genomebits,genomebits_alt,novelsplicingp);
  debug13(printf("(2) Spliceends_qend_trim returns trimpos %d and %d nmismatches, splice3 prob %f\n",
		 trimpos,nmismatches_to_trimpos,ambig_prob_3));

  if (trimpos == splice_qpos) {
    debug13(printf("New splice does not have a good distal segment\n"));
    return (T) NULL;

  } else {
    newpath = Path_copy_3(path,splice3p,splicetype3,ambig_prob_3,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

    debug13(printf("(1) attach_splice_qend (splice) is modifying path %p\n",path));
    debug13(printf("Adding an intron on top of qend diagonal with splice pos %d: %u to %u\n",
		   splice_qpos,medial_univdiagonal - chroffset,distal_univdiagonal - chroffset));
    debug13(printf("Before addition\n"));
    debug13(Path_print(newpath));

    if (splice_qpos == Intlist_head(newpath->endpoints)) {
      /* No change, so can keep nmismatches */
    } else if (splice_qpos < Intlist_head(newpath->endpoints) && Intlist_head(newpath->nmismatches) == 0) {
      /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
      Intlist_head_set(newpath->endpoints,splice_qpos);
    } else {
      /* Need to re-compute nmismatches */
      Intlist_head_set(newpath->endpoints,splice_qpos);
      Intlist_head_set(newpath->nmismatches,-1); /* From previous endpoint to splice_qpos */
      Intlist_head_set(newpath->ref_nmismatches,-1); /* From previous endpoint to splice_qpos */
    }
    newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,trimpos
					  intlistpool_trace(__FILE__,__LINE__));

    newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_to_trimpos
					    intlistpool_trace(__FILE__,__LINE__)); /* From splice_qpos to trimpos */
    newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_to_trimpos
						intlistpool_trace(__FILE__,__LINE__)); /* From splice_qpos to trimpos */
       
    newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,distal_univdiagonal
						    univcoordlistpool_trace(__FILE__,__LINE__));

    splice_distance = (Chrpos_T) (distal_univdiagonal - medial_univdiagonal);
    if (plusp) {
      if (found_sensedir == SENSE_FORWARD) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									/*donor_prob*/medial_prob,/*acceptor_prob*/distal_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else if (found_sensedir == SENSE_ANTI) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									/*donor_prob*/distal_prob,/*acceptor_prob*/medial_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else {
	fprintf(stderr,"Unexpected sensedir %d\n",found_sensedir);
	abort();
      }
    } else {
      if (found_sensedir == SENSE_ANTI) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									/*donor_prob*/medial_prob,/*acceptor_prob*/distal_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else if (found_sensedir == SENSE_FORWARD) {
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									/*donor_prob*/distal_prob,/*acceptor_prob*/medial_prob,
									pathpool)
					   listpool_trace(__FILE__,__LINE__));
      } else {
	fprintf(stderr,"Unexpected sensedir %d\n",found_sensedir);
	abort();
      }
    }    
	  
    newpath->splice3p = false;
    newpath->splicetype3 = NO_SPLICE;
    newpath->ambig_prob_3 = 0.0;

    debug13(printf("After addition\n"));
    debug13(Path_print(newpath));

    assert(newpath != path);
    return newpath;
  }
}



/* Adds a diagonal to the end of a path, as found by
   compute_qend_local.  Calls attach_unknown_qend to modify the path,
   potentially leading to multiple paths */
static List_T
multiadd_splice_qends (T path, Univcoord_T univdiagonal,
		       int common_splice_qpos, double common_splice_prob,
		       Univcoord_T *distal_splice_positions, int *distal_nmismatches,
		       double *distal_probs, int npartners,
		       Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh, int querylength, 
		       Compress_T query_compress, char *queryptr, bool plusp, int genestrand,
		       Knownsplicing_T knownsplicing,
		       Spliceendsgen_T spliceendsgen, int *mismatch_positions_alloc,
		       Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		       Listpool_T listpool, Hitlistpool_T hitlistpool, Pathpool_T pathpool,
		       Vectorpool_T vectorpool, int found_sensedir) {
  T newpath;
  Univcoord_T distal_univdiagonal;

  debug13(printf("Entered multiadd_splice_qends with %d partners at univdiagonal %u, common_splice_qpos %d.  Current path: ",
		 npartners,univdiagonal,common_splice_qpos));
  debug13(Path_print(path));
  debug13(printf("\n"));

  if (npartners == 1) {
    assert(distal_splice_positions[0] != 0);
    distal_univdiagonal = distal_splice_positions[0] - common_splice_qpos + querylength;    
    if (distal_univdiagonal == univdiagonal) {
      /* Not a splice.  Not sure whether to continue the alignment */
#if 0
      debug13(printf("Continuing the alignment to the end\n"));
      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
      Intlist_head_set(newpath->endpoints,querylength);
      Intlist_head_set(newpath->nmismatches,-1);
      Intlist_head_set(newpath->ref_nmismatches,-1);

      debug13(Path_print(newpath));
      return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(newpath)
			  hitlistpool_trace(__FILE__,__LINE__));
#else
      return (List_T) NULL;
#endif

    } else if ((newpath = attach_splice_qend(path,common_splice_qpos,querylength,plusp,genestrand,found_sensedir,
					     /*medial_prob*/common_splice_prob,/*distal_prob*/distal_probs[0],
					     /*medial_univdiagonal*/univdiagonal,distal_univdiagonal,
#if 0
					     distal_nmismatches[0],/*distal_ref_nmismatches*/distal_nmismatches[0],
#endif
					     chrnum,chroffset,chrhigh,knownsplicing,
					     spliceendsgen,mismatch_positions_alloc,query_compress,queryptr,
					     intlistpool,univcoordlistpool,listpool,pathpool,vectorpool)) == NULL) {
      return (List_T) NULL;
    } else {
      assert(newpath != path);
      return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(newpath)
			  hitlistpool_trace(__FILE__,__LINE__));
    }

  } else if (0) {
    /* TODO: Need an indicator that we did not reach to the end.  Then store each path separately */

  } else {
    /* Extends to the start, so create an alt substring */
    debug13(printf("Creating an alt substring\n"));
    newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			  intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
    Intlist_head_set(newpath->endpoints,common_splice_qpos);
    Intlist_head_set(newpath->nmismatches,-1);
    Intlist_head_set(newpath->ref_nmismatches,-1);

    debug13(printf("Combining qend alts for path:\n"));
    debug13(Path_print(newpath));

    newpath->qend_alts = Altsplice_new(/*distal_length*/querylength - common_splice_qpos,/*medial_prob*/common_splice_prob,
				       distal_splice_positions,distal_nmismatches,distal_probs,npartners,
				       pathpool,vectorpool);

#if 0
    newpath->endpoints = Intlistpool_pop(newpath->endpoints,&ignore_int
					 intlistpool_trace(__FILE__,__LINE__));
    newpath->junctions = Listpool_pop(newpath->junctions,(void **) &junction
				      listpool_trace(__FILE__,__LINE__));
    Junction_free(&junction,pathpool);
    newpath->nmismatches = Intlistpool_pop(newpath->nmismatches,&ignore_int
					   intlistpool_trace(__FILE__,__LINE__));
    newpath->ref_nmismatches = Intlistpool_pop(newpath->ref_nmismatches,&ignore_int
					       intlistpool_trace(__FILE__,__LINE__));
    newpath->univdiagonals = Univcoordlistpool_pop(newpath->univdiagonals,&ignore_univcoord
						   univcoordlistpool_trace(__FILE__,__LINE__));
#endif

    debug13(printf("(4) Resulting path: "));
    debug13(Path_print(newpath));
    debug13(printf("add_qend_local is returning path %p as newpaths\n",newpath));

    assert(newpath != path);
    return Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(newpath)
			hitlistpool_trace(__FILE__,__LINE__));
  }
}


/* Implements the addition of a diagonal to the end of a path.
   Returns a Path_T object, or NULL if the diagonal cannot
   be attached.  All Path_T objects are copies of the original path */

/* Returns newpath, which is different from path */
static T
attach_unknown_qend (T path, Univcoord_T high_univdiagonal, int high_qstart, int high_qend,
		     Univcoord_T chroffset, Univcoord_T chrhigh, int querylength,
		     Indelinfo_T indelinfo, Spliceinfo_T spliceinfo, Knownsplicing_T knownsplicing,
		     Compress_T query_compress, bool plusp, int genestrand,
		     int max_insertionlen, int max_deletionlen,
		     Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		     Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
		     Vectorpool_T vectorpool, int try_sensedir, bool salvagep) {
  T newpath = NULL;
  Univcoord_T univdiagonal, left;
  int qstart, ninserts;
  int nindels, indel_pos, splice_qpos, splice_qpos_i, splice_qpos_j;
  Univcoord_T middle_univdiagonal, deletionpos;
  Chrpos_T splice_distance, splice_distance_i, splice_distance_j;
  double donor_prob, acceptor_prob;
  int supporti, supportj;
  int nmismatches_i, nmismatches_j, nmismatches_indel,
    ref_nmismatches_i, ref_nmismatches_j, ref_nmismatches_indel,
    nmismatches, ref_nmismatches, nmismatches_middle, ref_nmismatches_middle;
#ifdef DEBUG13
  int qend;
#endif


  if (high_univdiagonal < (Univcoord_T) (querylength - high_qstart)) {
    /* high segment is before the beginning of the genome */
    return (T) NULL;
  } else {
    univdiagonal = Univcoordlist_head(path->univdiagonals);
  }

  /* Should not need to check for high_univdiagonal >= genomelength, since that should be true */


#if 0
  ninserts = Junction_total_ninserts(path->junctions);
#else
  if (path->junctions == NULL) {
    ninserts = 0;
  } else {
    ninserts = Junction_ninserts(List_head(path->junctions));
  }
#endif

  /* Assume that left+qstart gives a coordinate within genome */
  qstart = Intlist_second_value(path->endpoints) + ninserts;

#ifdef DEBUG13
  qend = Intlist_head(path->endpoints) /*+ ninserts*/;
  printf("Entering attach_unknown_qend with try_sensedir %d, univdiagonal %u %d..%d and high_univdiagonal %u (diff %d)\n",
	 try_sensedir,univdiagonal - chroffset,qstart,qend,high_univdiagonal - chroffset,high_univdiagonal - univdiagonal);
#endif

  if (qstart >= high_qend) {
    debug13(printf("Does not add to end of path: qstart %d >= high_qend %d\n",qstart,high_qend));
    
  } else if (high_univdiagonal + high_qend >= chrhigh + querylength) {
    debug13(printf("Extends beyond end of chromosome: high_univdiagonal %u - querylength %d + high_qend %d vs chrhigh %u\n",
		   high_univdiagonal,querylength,high_qend,chrhigh));

  } else if (high_univdiagonal == univdiagonal) {
    if (high_qend <= Intlist_head(path->endpoints)) {
      debug13(printf("Mismatch fails, since new endpoint %d <= old endpoint %d\n",high_qend,Intlist_head(path->endpoints)));

    } else {
      /* Mismatch: Revise the endpoint */
      debug13(printf("Mismatch extends from %d to %d\n",Intlist_head(path->endpoints),high_qend));
      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
      
      /* Determine nmismatches */
      if (path->junctions == NULL) {
	ninserts = 0;
      } else {
	ninserts = Junction_ninserts(List_head(path->junctions));
      }
      nmismatches = Genomebits_count_mismatches_substring(&ref_nmismatches,genomebits,genomebits_alt,query_compress,
							  univdiagonal,querylength,
							  /*pos5*/Intlist_head(Intlist_next(newpath->endpoints)) + ninserts,
							  /*pos3*/high_qend,plusp,genestrand);
      /* debug13(printf("Counting mismatches from %d to %d => %d (%d ref)\n",
	 Intlist_head(Intlist_next(newpath->endpoints)),high_qend,nmismatches,ref_nmismatches)); */

      debug13(printf("(2) attach_unknown_qend is modifying path %p\n",newpath));
      Intlist_head_set(newpath->nmismatches,nmismatches);
      Intlist_head_set(newpath->ref_nmismatches,nmismatches);
      Intlist_head_set(newpath->endpoints,high_qend);
    }

  } else if (high_univdiagonal + max_insertionlen < univdiagonal) {
    /* Impossible */
    debug13(printf("Impossible\n"));

  } else if (high_univdiagonal < univdiagonal) {
    /* (A) Insertion */
    nindels = univdiagonal - high_univdiagonal;
    if ((indel_pos = Indel_resolve_middle_insertion(&nmismatches_i,&nmismatches_j,
						    &ref_nmismatches_i,&ref_nmismatches_j,
						    univdiagonal,/*indels*/+nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						    /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						    /*pos5*/qstart,/*pos3*/high_qend,querylength,
						    indelinfo,plusp,genestrand,
						    /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("(4) Insertion fails\n"));

    } else {
      supporti = indel_pos - qstart;
      supportj = high_qend - (indel_pos + nindels);
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			      intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
	debug13(printf("(3) attach_unknown_qend is modifying path %p\n",newpath));
	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_insertion(nindels,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	debug13(printf("Insertion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		       qstart,high_qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
	
	debug13(Path_print(newpath));
      }
    }

  } else if (high_univdiagonal <= univdiagonal + max_deletionlen) {
    /* (B) Deletion (or short intron) */
    nindels = high_univdiagonal - univdiagonal;
    if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						   &ref_nmismatches_i,&ref_nmismatches_j,
						   /*univdiagonal_i*/univdiagonal,/*indels*/-nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						   /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						   /*pos5*/qstart,/*pos3*/high_qend,querylength,
						   indelinfo,plusp,genestrand,
						   /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("Deletion or short intron fails\n"));
      
    } else {
      supporti = indel_pos - qstart;
      supportj = high_qend - indel_pos;
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			      intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	
	assert(nindels >= 0);
	deletionpos = (univdiagonal - querylength) + indel_pos;
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	debug13(printf("(4) attach_unknown_qend is modifying path %p\n",newpath));
	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	debug13(printf("Deletion in range %d..%d is at %d with %d indels and nmismatches %d+%d\n",
		       qstart,high_qend,indel_pos,nindels,nmismatches_i,nmismatches_j));
	
	debug13(Path_print(newpath));
      }
    }
    
#ifdef DISALLOW_CIRCULAR_SPLICING
  } else if (circularp[chrnum] == true) {
    /* No splicing on circular chromosomes */
    debug13(printf("No splicing on circular chromosomes\n"));
#endif

  } else {
    /* (C) Splice with or without indel */
    left = univdiagonal - (Univcoord_T) querylength;
    /* high_left = high_univdiagonal - (Univcoord_T) querylength; */

    /* Previously filled spliceinfo with knownsplicing information on donors and antiacceptors for segmenti, now done in Splice_resolve_sense */
    /* Previously filled spliceinfo with knownsplicing information on acceptors and antidonors for segmentj, now done in Splice_resolve_sense */

    if (try_sensedir == SENSE_FORWARD) {
      /* (C1) Sense */
      /* left = univdiagonal - querylength; -- Computed above */
      /* high_left = high_univdiagonal - querylength; -- Combined above */

      debug13(printf("BEFORE call to Splice_resolve, %d..%d\n",qstart,high_qend));
      debug13(Path_print(path));

      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					/*univdiagonal_i*/univdiagonal,/*univdiagonal_j*/high_univdiagonal,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/qstart,/*pos3*/high_qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/true,
					genestrand,max_insertionlen,max_deletionlen,
					salvagep,/*check_support_p*/true)) < 0) {
	debug13(printf("(5) attach_unknown_qend is modifying path %p\n",newpath));

	if (middle_univdiagonal != 0) {
	  debug13(printf("Splice_resolve (qend, sense): found a middle exon\n"));
	  splice_distance_j = high_univdiagonal - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - univdiagonal;
	
	  debug13(printf("(6) attach_unknown_qend is modifying path %p\n",newpath));
	  Intlist_head_set(newpath->endpoints,splice_qpos_i);
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos_j
						intlistpool_trace(__FILE__,__LINE__));
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
						intlistpool_trace(__FILE__,__LINE__));
	  
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_i,SENSE_FORWARD,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_j,SENSE_FORWARD,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	
	  /* For qend, push i first, then push j */
	  Intlist_head_set(newpath->nmismatches,nmismatches_i);
	  Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_middle
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_middle
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						      intlistpool_trace(__FILE__,__LINE__));
	
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));

	  debug13(Path_print(newpath));

	} else {
	  debug13(printf("Splice_resolve (qend, sense): fails\n"));

#if 0
	  /* Put in a temporary junction, to be fixed later if it is worth it */
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
						intlistpool_trace(__FILE__,__LINE__));
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) Junction_new_unsolved(pathpool)
					     listpool_trace(__FILE__,__LINE__));
#else
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) JUNCTION_UNSOLVED
					     listpool_trace(__FILE__,__LINE__));
#endif

	  Intlist_head_set(newpath->nmismatches,-1);
	  Intlist_head_set(newpath->ref_nmismatches,-1);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,-1
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,-1
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  debug13(printf("attach_unknown_qend is returning a path %p with an unsolved junction\n",newpath));
#endif

#if 0
	  /* Put into qstart direction */
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
					 (void *) Path_reverse(newpath,/*expect_fwd_p*/true)
					 hitlistpool_trace(__FILE__,__LINE__));
#else
	  Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
#endif
	  newpath = (T) NULL;
	}

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = high_univdiagonal - univdiagonal;
	debug13(printf("Splice_resolve (qend, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));
	
	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else if (indel_pos < splice_qpos) {
	/* Push indel (based on left) then splice.  indel is medial, splice is distal. */
	middle_univdiagonal = univdiagonal + nindels; /* nindels = middle_univdiagonal - univdiagonal */
	splice_distance = high_univdiagonal - middle_univdiagonal;

	debug13(printf("Splice_resolve (qend, sense): %d indels at %d, nmismatches %d, then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,nmismatches_indel,
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Indel first */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = left + indel_pos; /* qend; do not add splice_distance if indel first */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on high_univdiagonal).  splice is medial, indel is distal. */
	middle_univdiagonal = high_univdiagonal - nindels; /* nindels = high_univdiagonal - middle_univdiagonal */
	splice_distance = middle_univdiagonal - univdiagonal;

	debug13(printf("Splice_resolve (qend, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d\n",
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,indel_pos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = left + splice_distance + indel_pos; /* qend; add splice_distance if indel second */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
      }

      debug13(printf("AFTER call to Splice_resolve\n"));
      debug13(Path_print(newpath));
      
    } else {
      /* (C2) Antisense */
      /* left = univdiagonal - querylength; -- Computed above */
      /* high_left = high_univdiagonal - querylength; -- Computed above */
      
      /* Previously did not fill spliceinfo with knownsplicing info, now done in Splice_resolve_antisense */
      
      debug13(printf("BEFORE call to Splice_resolve, %d..%d\n",qstart,high_qend));
      debug13(Path_print(path));

      newpath = Path_copy_3(path,/*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
			    intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
      debug13(Path_print(newpath));

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					/*univdiagonal_i*/univdiagonal,/*univdiagonal_j*/high_univdiagonal,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/qstart,/*pos3*/high_qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/false,
					genestrand,max_insertionlen,max_deletionlen,
					salvagep,/*check_support_p*/true)) < 0) {
	debug13(printf("(7) attach_unknown_qend is modifying path %p\n",newpath));

	if (middle_univdiagonal != 0) {
	  debug13(printf("Splice_resolve (qend, antisense): found a middle exon\n"));
	  splice_distance_j = high_univdiagonal - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - univdiagonal;
	
	  debug13(printf("(8) attach_unknown_qend is modifying path %p\n",newpath));
	  Intlist_head_set(newpath->endpoints,splice_qpos_i);
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos_j
						intlistpool_trace(__FILE__,__LINE__));
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
						intlistpool_trace(__FILE__,__LINE__));
	
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_i,SENSE_ANTI,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_splice(splice_distance_j,SENSE_ANTI,
									  /*donor_prob*/1.0,/*acceptor_prob*/1.0,
									  pathpool)
					     listpool_trace(__FILE__,__LINE__));
	
	  /* For qend, push i first, then push j */
	  Intlist_head_set(newpath->nmismatches,nmismatches_i);
	  Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_middle
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_middle
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						      intlistpool_trace(__FILE__,__LINE__));
	
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	
	  debug13(Path_print(newpath));

	} else {
	  debug13(printf("Splice_resolve (qend, antisense): fails\n"));

#if 0
	  /* Put in a temporary junction, to be fixed later if it is worth it */
	  newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
						intlistpool_trace(__FILE__,__LINE__));
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) Junction_new_unsolved(pathpool)
					     listpool_trace(__FILE__,__LINE__));
#else
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,(void *) JUNCTION_UNSOLVED
					     listpool_trace(__FILE__,__LINE__));
#endif
	
	  Intlist_head_set(newpath->nmismatches,-1);
	  Intlist_head_set(newpath->ref_nmismatches,-1);
	  newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,-1
						  intlistpool_trace(__FILE__,__LINE__));
	  newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,-1
						      intlistpool_trace(__FILE__,__LINE__));
	  newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							  univcoordlistpool_trace(__FILE__,__LINE__));
	  debug13(printf("attach_unknown_qend is returning a path %p with an unsolved junction\n",newpath));
#endif
#if 0
	  /* Put into qstart direction */
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
					 (void *) Path_reverse(newpath,/*expect_fwd_p*/true)
					 hitlistpool_trace(__FILE__,__LINE__));
#else
	  Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
#endif
	  newpath = (T) NULL;
	}

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = high_univdiagonal - univdiagonal;
	debug13(printf("Splice_resolve (qend, antisense): splice_qpos in range %d..%d is at %d with distance %u, nmismatches %d+%d, and probs %f and %f\n",
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else if (indel_pos < splice_qpos) {
	/* Push indel (based on left) then splice.  indel is medial, splice is distal. */
	middle_univdiagonal = univdiagonal + nindels; /* nindels = middle_univdiagonal - univdiagonal */
	splice_distance = high_univdiagonal - middle_univdiagonal;

	debug13(printf("Splice_resolve (qend, antisense): %d indels at %d then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(newpath->endpoints,indel_pos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,splice_qpos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Indel first */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = left + indel_pos; /* qend; do not add splice_distance if indel first */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* For qend, push i first, then push j */
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on high_univdiagonal).  splice is medial, indel is distal. */
	middle_univdiagonal = high_univdiagonal - nindels; /* nindels = high_univdiagonal - middle_univdiagonal */
	splice_distance = middle_univdiagonal - univdiagonal;

	debug13(printf("Splice_resolve (qend, antisense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d\n",
		       qstart,high_qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos));

	Intlist_head_set(newpath->endpoints,splice_qpos);
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,indel_pos
					      intlistpool_trace(__FILE__,__LINE__));
	newpath->endpoints = Intlistpool_push(newpath->endpoints,intlistpool,high_qend
					      intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	newpath->junctions = Listpool_push(newpath->junctions,listpool,
					   (void *) Junction_new_splice(splice_distance,SENSE_ANTI,
									donor_prob,acceptor_prob,pathpool)
					   listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	if (nindels < 0) {
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_insertion(-nindels,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = left + splice_distance + indel_pos; /* qend; add splice_distance if indel second */
	  newpath->junctions = Listpool_push(newpath->junctions,listpool,
					     (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					     listpool_trace(__FILE__,__LINE__));
	}
	  
	Intlist_head_set(newpath->nmismatches,nmismatches_i);
	Intlist_head_set(newpath->ref_nmismatches,ref_nmismatches_i);
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_indel
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,nmismatches_indel
						    intlistpool_trace(__FILE__,__LINE__));
	newpath->nmismatches = Intlistpool_push(newpath->nmismatches,intlistpool,nmismatches_j
						intlistpool_trace(__FILE__,__LINE__));
	newpath->ref_nmismatches = Intlistpool_push(newpath->ref_nmismatches,intlistpool,ref_nmismatches_j
						    intlistpool_trace(__FILE__,__LINE__));
	  
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,middle_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
	newpath->univdiagonals = Univcoordlistpool_push(newpath->univdiagonals,univcoordlistpool,high_univdiagonal
							univcoordlistpool_trace(__FILE__,__LINE__));
      } 
      debug13(printf("AFTER call to Splice_resolve\n"));
      debug13(Path_print(newpath));
    }
  }

  debug13(printf("attach_unknown_qend is returning newpath %p\n",newpath));

  assert(newpath != path);
  return newpath;
}



/* Sometimes merging of left and right paths can result in anomalies */
static bool
endpoints_acceptable_p (Intlist_T endpoints, List_T junctions) {
  Intlist_T p;
  List_T q;
  Junction_T junction;
  int last_endpoint;

  debug2(printf("Evaluating endpoints for acceptability: %s\n",Intlist_to_string(endpoints)));

  /* last_endpoint = 0; */
  /* Skip first endpoint */
  for (p = Intlist_next(endpoints), q = junctions; Intlist_next(p) != NULL; p = Intlist_next(p), q = List_next(q)) {
    last_endpoint = Intlist_head(p);
    junction = (Junction_T) List_head(q);
    if (last_endpoint + Junction_ninserts(junction) >= Intlist_head(Intlist_next(p))) {
      debug2(printf("Endpoint %d + %d >= %d, so unacceptable\n",
		    last_endpoint,Junction_ninserts(junction),Intlist_head(Intlist_next(p))));
      return false;
    } else {
      debug2(printf("Endpoint %d + %d < %d, so acceptable\n",
		    last_endpoint,Junction_ninserts(junction),Intlist_head(Intlist_next(p))));
    }
  }

  return true;
}


#if 0
/* Ignores values of -1 (unknown) */
static int
preliminary_score_within_trims (Intlist_T nmismatches) {
  int score = 0;
  Intlist_T p;

  for (p = nmismatches; p != NULL; p = Intlist_next(p)) {
    if (Intlist_head(p) >= 0) {
      score += Intlist_head(p);
    }
  }

  return score;
}
#endif


/* Modified from Path_exon_origin */
static int
compute_exon_origin (Intlist_T endpoints, List_T junctions) {
  int exon_origin;
  Intlist_T p = endpoints;
  List_T j = junctions;

  p = Intlist_next(p);
  exon_origin = Intlist_head(p);

  while (j != NULL && Junction_type((Junction_T) List_head(j)) != SPLICE_JUNCTION) {
    p = Intlist_next(p);
    exon_origin = Intlist_head(p);

    j = List_next(j);
  }

  return exon_origin;
}




/* Always solves against plus strand of genome.  Just provide either
   queryuc/query_compress_fwd (coords measured from beginning of
   sequence) or queryrc/query_compress_rev (coords measured from end
   of sequence).  All coordinates measured from low end.
   Sense/antisense is with respect to the plus strand.  But to
   interface with Stage3end_new_substrings command, need to flip
   coordinates for case where queryrc aligns to plus strand. */

/* chrnum is fixed from middle_diagonal */
static List_T
combine_leftright_paths (int *found_score, List_T qstart_paths, List_T qend_paths,
			 Compress_T query_compress, Compress_T query_compress_fwd,
			 Compress_T query_compress_rev, char *queryptr, int querylength,
			 bool plusp, int genestrand, int sensedir,
			 Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
			 int *mismatch_positions_alloc, Knownsplicing_T knownsplicing,
			 Spliceendsgen_T spliceendsgen,
			 Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
			 Listpool_T listpool, Pathpool_T pathpool,
			 Vectorpool_T vectorpool, Hitlistpool_T hitlistpool, Method_T method) {
  List_T paths = NULL, best_qstart_paths, best_qend_paths;
  List_T a, b;
  T path, qstart_path, qend_path;

  int best_nmatches, best_ref_nmatches, nmatches;
  double best_splice_prob;

  Intlist_T endpoints, q;
  Univcoordlist_T univdiagonals, u;
  Intlist_T nmismatches, ref_nmismatches, s, r;
  List_T junctions, j;
  Junction_T junction;

  int qstart1, qend1, qstart2, qend2;
  int middle_nmismatches, middle_ref_nmismatches;
  int ignore_found_score = querylength;

  int found_sensedir;
  int trimpos, ninserts, exon_origin, qstart, qend;
  int nmismatches_to_trimpos;
  bool splice5p, splice3p;
  Splicetype_T splicetype5, splicetype3;
  double ambig_prob_5, ambig_prob_3;



#ifdef DEBUG13
  printf("\n");
  printf("*** Entered combine_leftright_paths with %d qstart paths and %d qend paths\n",
	 List_length(qstart_paths),List_length(qend_paths));
#endif

  /* assert(qstart_paths != NULL && qend_paths != NULL); */

  /* Find best qstart paths */
  if (List_length(qstart_paths) == 1) {
    best_qstart_paths = Hitlist_copy(qstart_paths,hitlistpool);

  } else {
    best_qstart_paths = (List_T) NULL;
    best_nmatches = 0;
    best_ref_nmatches = 0;
    best_splice_prob = 0.0;
    for (a = qstart_paths; a != NULL; a = List_next(a)) {
      qstart_path = (T) List_head(a);
      nmatches = Path_eval_nmatches(&ignore_found_score,qstart_path,
				    query_compress_fwd,query_compress_rev);
      if (nmatches < best_nmatches) {
	/* Worse than current best */
	debug13(printf("=> (X) Worse than current best by nmatches\n"));

      } else if (nmatches > best_nmatches) {
	/* Better than current best */
	Hitlistpool_free_list(&best_qstart_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qstart_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(qstart_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	best_nmatches = nmatches;
	best_ref_nmatches = qstart_path->ref_nmatches;
	best_splice_prob = qstart_path->junction_splice_prob;

      } else if (qstart_path->ref_nmatches < best_ref_nmatches) {
	/* Worse than current best */
	debug13(printf("=> (Y) Worse than current best by ref_nmatches\n"));

      } else if (qstart_path->ref_nmatches > best_ref_nmatches) {
	/* Better than current best */
	Hitlistpool_free_list(&best_qstart_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qstart_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(qstart_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	/* best_nmatches = nmatches; */
	best_ref_nmatches = qstart_path->ref_nmatches;
	best_splice_prob = qstart_path->junction_splice_prob;

      } else if (qstart_path->junction_splice_prob < best_splice_prob) {
	/* Worse than current best */
	debug13(printf("=> (Z) Worse than current best by splice_prob\n"));

      } else if (qstart_path->junction_splice_prob > best_splice_prob) {
	Hitlistpool_free_list(&best_qstart_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qstart_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_fwd(qstart_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	/* best_nmatches = nmatches; */
	/* best_ref_nmatches = qstart_path->ref_nmatches; */
	best_splice_prob = qstart_path->junction_splice_prob;

      } else {
	/* Same as current best */
	best_qstart_paths = Hitlist_push(best_qstart_paths,hitlistpool,(void *) Path_expect_fwd(qstart_path)
					 hitlistpool_trace(__FILE__,__LINE__));
      }
    }
  }
    
  /* Find best qend paths */
  if (List_length(qend_paths) == 1) {
    best_qend_paths = Hitlist_copy(qend_paths,hitlistpool);

  } else {
    best_qend_paths = (List_T) NULL;
    best_nmatches = 0;
    best_ref_nmatches = 0;
    best_splice_prob = 0.0;

    for (b = qend_paths; b != NULL; b = List_next(b)) {
      qend_path = (T) List_head(b);

      Path_reverse(qend_path,/*expect_fwd_p*/true);
      nmatches = Path_eval_nmatches(&ignore_found_score,qend_path,
				    query_compress_fwd,query_compress_rev);
      Path_reverse(qend_path,/*expect_fwd_p*/false);

      if (nmatches < best_nmatches) {
	/* Worse than current best */
	debug13(printf("=> (X) Worse than current best by nmatches\n"));

      } else if (nmatches > best_nmatches) {
	/* Better than current best */
	Hitlistpool_free_list(&best_qend_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qend_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(qend_path)
				       hitlistpool_trace(__FILE__,__LINE__));
	best_nmatches = nmatches;
	best_ref_nmatches = qend_path->ref_nmatches;
	best_splice_prob = qend_path->junction_splice_prob;

      } else if (qend_path->ref_nmatches < best_ref_nmatches) {
	/* Worse than current best */
	debug13(printf("=> (Y) Worse than current best by ref_nmatches\n"));

      } else if (qend_path->ref_nmatches > best_ref_nmatches) {
	/* Better than current best */
	Hitlistpool_free_list(&best_qend_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qend_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(qend_path)
				       hitlistpool_trace(__FILE__,__LINE__));
	/* best_nmatches = nmatches; */
	best_ref_nmatches = qend_path->ref_nmatches;
	best_splice_prob = qend_path->junction_splice_prob;

      } else if (qend_path->junction_splice_prob < best_splice_prob) {
	/* Worse than current best */
	debug13(printf("=> (Z) Worse than current best by splice_prob\n"));

      } else if (qend_path->junction_splice_prob > best_splice_prob) {
	Hitlistpool_free_list(&best_qend_paths,hitlistpool
			      hitlistpool_trace(__FILE__,__LINE__));
	best_qend_paths = Hitlist_push(NULL,hitlistpool,(void *) Path_expect_rev(qend_path)
				       hitlistpool_trace(__FILE__,__LINE__));
	/* best_nmatches = nmatches; */
	/* best_ref_nmatches = qend_path->ref_nmatches; */
	best_splice_prob = qend_path->junction_splice_prob;

      } else {
	/* Same as current best */
	best_qend_paths = Hitlist_push(best_qend_paths,hitlistpool,(void *) Path_expect_rev(qend_path)
				       hitlistpool_trace(__FILE__,__LINE__));
      }
    }
  }


  for (a = best_qstart_paths; a != NULL; a = List_next(a)) {
    qstart_path = (T) List_head(a);
    assert(qstart_path->sensedir == sensedir);

    for (b = best_qend_paths; b != NULL; b = List_next(b)) {
      qend_path = (T) List_head(b);
      assert(qend_path->sensedir == sensedir);
	
      debug13(printf("++ Qstart/left path %p: ",qstart_path));
      debug13(Path_print(qstart_path));
      debug13(printf("++ Qend/right path %p: ",qend_path));
      debug13(Path_print(qend_path));
      debug13(printf("\n"));

      /* Combine qstart_path with qend_path */
      /* If either list is NULL, must have obtained an unacceptable result */
	
      /* Example:
	 qstart_path->endpoints:        59(qstart1), 77(qend1).
	 qend_path->endpoints: 100, 79, 68(qend2),   57(qstart2).
	   
	 endpoints1:           59                77
	 endpoints2:        57               68, 79, 100
	   
	 Desired result: 57, 68, 79, 100.
	   
	 Could use middle_univdiagonal to find the original, common
	 segment, but it should be the last segment in each case,
	 since we pushed results on top for qstart and for qend */

      /* endpoints = (Intlist_T) NULL; -- Initialized with first push */
      univdiagonals = (Univcoordlist_T) NULL;
      nmismatches = (Intlist_T) NULL;
      ref_nmismatches = (Intlist_T) NULL;
      junctions = (List_T) NULL;
	
      qend1 = Intlist_last_value(qstart_path->endpoints);
      qstart1 = Intlist_penultimate_value(qstart_path->endpoints);
	
      qstart2 = Intlist_last_value(qend_path->endpoints);
      qend2 = Intlist_penultimate_value(qend_path->endpoints);
	
      q = qstart_path->endpoints;
      u = qstart_path->univdiagonals;
      s = qstart_path->nmismatches;
      r = qstart_path->ref_nmismatches;
      j = qstart_path->junctions;
	
      junction = (Junction_T) NULL;
      endpoints = Intlistpool_push(NULL,intlistpool,Intlist_head(q)
				   intlistpool_trace(__FILE__,__LINE__));
      q = Intlist_next(q);
      while (j != NULL) {
	endpoints = Intlistpool_push(endpoints,intlistpool,Intlist_head(q)
				     intlistpool_trace(__FILE__,__LINE__));
	univdiagonals = Univcoordlistpool_push(univdiagonals,univcoordlistpool,Univcoordlist_head(u)
					       univcoordlistpool_trace(__FILE__,__LINE__));
	nmismatches = Intlistpool_push(nmismatches,intlistpool,Intlist_head(s)
				       intlistpool_trace(__FILE__,__LINE__));
	ref_nmismatches = Intlistpool_push(ref_nmismatches,intlistpool,Intlist_head(r)
					   intlistpool_trace(__FILE__,__LINE__));
	junctions = Listpool_push(junctions,listpool,(void *) Junction_copy((Junction_T) List_head(j),pathpool)
				  listpool_trace(__FILE__,__LINE__));
	q = Intlist_next(q);
	u = Univcoordlist_next(u);
	s = Intlist_next(s);
	r = Intlist_next(r);
	junction = (Junction_T) List_head(j);
	j = List_next(j);
      }
	
      /* Reached middle_univdiagonal of qstart1 */
      qstart1 = Intlist_head(endpoints);
      if (junction != NULL) {
	qstart1 += Junction_ninserts(junction);
      }
      qend1 = Intlist_head(q);
	


      Path_reverse(qend_path,/*expect_fwd_p*/true);
	
      qstart2 = Intlist_head(qend_path->endpoints);
      qend2 = Intlist_head(Intlist_next(qend_path->endpoints));

      if (qend2 <= qstart1) {
	/* No overlap */
	debug13(printf("++ Combined path not possible, due to lack of overlap between %d..%d and %d..%d\n",
		       qstart1,qend1,qstart2,qend2));
	Intlistpool_free_list(&endpoints,intlistpool
			      intlistpool_trace(__FILE__,__LINE__));
	Univcoordlistpool_free_list(&univdiagonals,univcoordlistpool
				    univcoordlistpool_trace(__FILE__,__LINE__));
	Intlistpool_free_list(&nmismatches,intlistpool
			      intlistpool_trace(__FILE__,__LINE__));
	Intlistpool_free_list(&ref_nmismatches,intlistpool
			      intlistpool_trace(__FILE__,__LINE__));
	Junction_list_gc(&junctions,listpool,pathpool);

      } else {
	endpoints = Intlistpool_push(endpoints,intlistpool,qend2
				     intlistpool_trace(__FILE__,__LINE__));
	univdiagonals = Univcoordlistpool_push(univdiagonals,univcoordlistpool,Univcoordlist_head(u)
					       univcoordlistpool_trace(__FILE__,__LINE__));

	if (qstart1 == qstart2 && qend1 == qend2) {
	  /* Take nmismatches from either qstart_path or qend_path (if available) */
	  if ((middle_nmismatches = Intlist_head(s)) == -1) {
	    middle_nmismatches = Intlist_head(qend_path->nmismatches);
	  }
	  if ((middle_ref_nmismatches = Intlist_head(r)) == -1) {
	    middle_ref_nmismatches = Intlist_head(qend_path->ref_nmismatches);
	  }
	  
	} else if (qstart1 == qstart2) {
	  /* Take nmismatches from either qend_path */
	  middle_nmismatches = Intlist_head(qend_path->nmismatches);
	  middle_ref_nmismatches = Intlist_head(qend_path->ref_nmismatches);
	  
	} else if (qend1 == qend2) {
	  /* Take nmismatches from either qstart_path */
	  middle_nmismatches = Intlist_head(s);
	  middle_ref_nmismatches = Intlist_head(r);
	  
	} else {
	  middle_nmismatches = -1;
	  middle_ref_nmismatches = -1;
	}
	nmismatches = Intlistpool_push(nmismatches,intlistpool,middle_nmismatches
				       intlistpool_trace(__FILE__,__LINE__));
	ref_nmismatches = Intlistpool_push(ref_nmismatches,intlistpool,middle_ref_nmismatches
					   intlistpool_trace(__FILE__,__LINE__));

	
	q = Intlist_next(qend_path->endpoints);
	u = qend_path->univdiagonals;
	s = qend_path->nmismatches;
	r = qend_path->ref_nmismatches;
	j = qend_path->junctions;
	
	while (j != NULL) {
	  junctions = Listpool_push(junctions,listpool,(void *) Junction_copy((Junction_T) List_head(j),pathpool)
				    listpool_trace(__FILE__,__LINE__));
	  q = Intlist_next(q);
	  u = Univcoordlist_next(u);
	  s = Intlist_next(s);
	  r = Intlist_next(r);
	  endpoints = Intlistpool_push(endpoints,intlistpool,Intlist_head(q)
				       intlistpool_trace(__FILE__,__LINE__));
	  univdiagonals = Univcoordlistpool_push(univdiagonals,univcoordlistpool,Univcoordlist_head(u)
						 univcoordlistpool_trace(__FILE__,__LINE__));
	  nmismatches = Intlistpool_push(nmismatches,intlistpool,Intlist_head(s)
					 intlistpool_trace(__FILE__,__LINE__));
	  ref_nmismatches = Intlistpool_push(ref_nmismatches,intlistpool,Intlist_head(r)
					     intlistpool_trace(__FILE__,__LINE__));
	  j = List_next(j);
	}

	endpoints = Intlist_reverse(endpoints);
	junctions = List_reverse(junctions);
	if (endpoints_acceptable_p(endpoints,junctions) == false) {
	  debug13(printf("++ Combined path not possible, due to unacceptable endpoints\n"));
	  Intlistpool_free_list(&endpoints,intlistpool
				intlistpool_trace(__FILE__,__LINE__));
	  Univcoordlistpool_free_list(&univdiagonals,univcoordlistpool
				      univcoordlistpool_trace(__FILE__,__LINE__));
	  Intlistpool_free_list(&nmismatches,intlistpool
				intlistpool_trace(__FILE__,__LINE__));
	  Intlistpool_free_list(&ref_nmismatches,intlistpool
				intlistpool_trace(__FILE__,__LINE__));
	  Junction_list_gc(&junctions,listpool,pathpool);

	} else {
	  univdiagonals = Univcoordlist_reverse(univdiagonals);
	  nmismatches = Intlist_reverse(nmismatches);
	  ref_nmismatches = Intlist_reverse(ref_nmismatches);

#if 0
	  if (preliminary_score_within_trims(nmismatches) > nmismatches_allowed) {
	    /* Previously, did not proceed, but now allowing the paths to combine */
	    debug1(printf("combine_leftright_paths: Not considering because preliminary score within trims %d > nmismatches_allowed %d\n",
			  preliminary_score_within_trims(nmismatches),nmismatches_allowed));
	    Intlistpool_free_list(&endpoints,intlistpool
				  intlistpool_trace(__FILE__,__LINE__));
	    Univcoordlistpool_free_list(&univdiagonals,univcoordlistpool
					univcoordlistpool_trace(__FILE__,__LINE__));
	    Intlistpool_free_list(&nmismatches,intlistpool
				  intlistpool_trace(__FILE__,__LINE__));
	    Intlistpool_free_list(&ref_nmismatches,intlistpool
				  intlistpool_trace(__FILE__,__LINE__));
	    Junction_list_gc(&junctions,listpool,pathpool);
	  } else {
#endif
	    if (qend_path->splice3p == true || qend_path->qend_alts != NULL || (qend = Intlist_last_value(endpoints)) == querylength) {
	      splice3p = qend_path->splice3p;
	      splicetype3 = qend_path->splicetype3;
	      ambig_prob_3 = qend_path->ambig_prob_3;
	    } else {
	      endpoints = Intlist_reverse(endpoints);
	      univdiagonals = Univcoordlist_reverse(univdiagonals);
	      junctions = List_reverse(junctions);
	      if (junctions == NULL) {
		ninserts = 0;
	      } else {
		ninserts = Junction_ninserts((Junction_T) List_head(junctions));
	      }

	      debug13(printf("endpoints: %s\n",Intlist_to_string(endpoints)));
	      debug13(printf("nmismatches: %s\n",Intlist_to_string(nmismatches)));

	      exon_origin = compute_exon_origin(endpoints,junctions);
	      debug13(printf("Calling Spliceends_qend_trim with pos5 %d\n",Intlist_head(Intlist_next(endpoints)) + ninserts));
	      splice3p = Spliceends_qend_trim(&trimpos,&nmismatches_to_trimpos,
					      &found_sensedir,&splicetype3,&ambig_prob_3,
					      knownsplicing,sensedir,
					      Univcoordlist_head(univdiagonals),querylength,
					      /*pos5*/Intlist_head(Intlist_next(endpoints)) + ninserts,
					      exon_origin,chrnum,chroffset,chrhigh,
					      plusp,genestrand,mismatch_positions_alloc,
					      spliceendsgen,query_compress,queryptr,
					      genomebits,genomebits_alt,novelsplicingp);
	      debug13(printf("(3) Spliceends_qend_trim returns trimpos %d and %d nmismatches, splice3 prob %f\n",
			     trimpos,nmismatches_to_trimpos,ambig_prob_3));

	      if (trimpos == Intlist_second_value(endpoints)) {
		debug13(printf("Segment is not great, since nosplice_trimpos erases segment, so not trimming\n"));

	      } else if (trimpos == qend) {
		/* No change, so can keep nmismatches */
		debug13(printf("No change, so keeping nmismatches as %d\n",Intlist_last_value(nmismatches)));

	      } else if (Univcoordlist_head(univdiagonals) - querylength + trimpos < chroffset) {
		debug13(printf("Attempt to trim beyond start of chromosome (%u < %u), so not trimming\n",
			       Univcoordlist_head(univdiagonals) - querylength + trimpos,chroffset));

	      } else if (trimpos <= Intlist_second_value(endpoints) + ninserts) {
		debug13(printf("Attempt to trim before an insertion (%d <= %d+%d), so not trimming\n",
			       trimpos,Intlist_second_value(endpoints),ninserts));
	      } else {
		/* Use new nmismatches_to_trimpos */
		debug13(printf("Changing 3' endpoint from %d to %d\n",Intlist_head(endpoints),trimpos));
		Intlist_head_set(endpoints,trimpos);

		nmismatches = Intlist_reverse(nmismatches);
		ref_nmismatches = Intlist_reverse(ref_nmismatches);
		Intlist_head_set(nmismatches,nmismatches_to_trimpos);
		Intlist_head_set(ref_nmismatches,nmismatches_to_trimpos);
		nmismatches = Intlist_reverse(nmismatches);
		ref_nmismatches = Intlist_reverse(ref_nmismatches);
	      }

	      endpoints = Intlist_reverse(endpoints);
	      univdiagonals = Univcoordlist_reverse(univdiagonals);
	      junctions = List_reverse(junctions);
	    }


	    if (qstart_path->splice5p == true || qstart_path->qstart_alts != NULL || (qstart = Intlist_head(endpoints)) == 0) {
	      splice5p = qstart_path->splice5p;
	      splicetype5 = qstart_path->splicetype5;
	      ambig_prob_5 = qstart_path->ambig_prob_5;
	    } else {
	      exon_origin = compute_exon_origin(endpoints,junctions);
	      debug13(printf("Calling Spliceends_qstart_trim with pos3 %d\n",Intlist_head(Intlist_next(endpoints))));
	      splice5p = Spliceends_qstart_trim(&trimpos,&nmismatches_to_trimpos,&found_sensedir,&splicetype5,&ambig_prob_5,
						knownsplicing,sensedir,
						Univcoordlist_head(univdiagonals),querylength,
						/*pos3*/Intlist_head(Intlist_next(endpoints)),
						exon_origin,chrnum,chroffset,
						plusp,genestrand,mismatch_positions_alloc,
						spliceendsgen,query_compress,queryptr,
						genomebits,genomebits_alt,novelsplicingp);
	      debug13(printf("(3) Spliceends_qstart_trim returns trimpos %d and %d nmismatches, splice5 prob %f\n",
			     trimpos,nmismatches_to_trimpos,ambig_prob_5));

	      if (trimpos == Intlist_second_value(endpoints)) {
		debug13(printf("Segment is not great, since nosplice_trimpos erases segment, so not trimming\n"));

	      } else if (trimpos == qstart) {
		/* No change, so can keep nmismatches */
		debug13(printf("No change, so keeping nmismatches as %d\n",Intlist_head(nmismatches)));

	      } else if (Univcoordlist_head(univdiagonals) - querylength + trimpos >= chrhigh) {
		debug13(printf("Attempt to trim beyond end of chromosome (%u > %u), so not trimming\n",
			       Univcoordlist_head(univdiagonals) - querylength + trimpos,chrhigh));
	      } else {
		/* Use new nmismatches_to_trimpos */
		debug13(printf("Changing 5' endpoint from %d to %d\n",Intlist_head(endpoints),trimpos));
		Intlist_head_set(endpoints,trimpos);
		Intlist_head_set(nmismatches,nmismatches_to_trimpos);
		Intlist_head_set(ref_nmismatches,nmismatches_to_trimpos);
	      }
	    }

	    path = Path_create(endpoints,univdiagonals,nmismatches,ref_nmismatches,junctions,
			       plusp,genestrand,sensedir,querylength,
			       method,chrnum,chroffset,chrhigh,
			       splice5p,splicetype5,ambig_prob_5,
			       splice3p,splicetype3,ambig_prob_3,
			       qstart_path->qstart_alts,qend_path->qend_alts,pathpool,vectorpool);
	    Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);
	    debug13(printf("++ Combined path %p: ",path));
	    debug13(Path_print(path));
	    debug13(printf("\n"));

#if 0
	    if (path->score_within_trims > nmismatches_allowed) {
	      /* Previously, did not allow, but now allowing the paths to combine */
	      debug13(printf("combine_leftright_paths: Not considering because score within trims %d > nmismatches_allowed %d\n",
			     path->score_within_trims,nmismatches_allowed));
	      Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
	    } else {
#endif
	      debug13(printf("combine_leftright_paths yields result with score %d\n",path->score_within_trims));
	      paths = Hitlist_push(paths,hitlistpool,(void *) Path_expect_fwd(path)
				   hitlistpool_trace(__FILE__,__LINE__));
#if 0
	    }
#endif
#if 0
	  }
#endif
	}
      }

      /* Undo reversal */
      Path_reverse(qend_path,/*expect_fwd_p*/false);
	
    }
  }
 
  Hitlistpool_free_list(&best_qend_paths,hitlistpool
			hitlistpool_trace(__FILE__,__LINE__));
  Hitlistpool_free_list(&best_qstart_paths,hitlistpool
			hitlistpool_trace(__FILE__,__LINE__));

#ifdef DEBUG13
  printf("\n");
  printf("*** Exiting combine_leftright_paths.  Paths now has length %d\n",List_length(paths));
#endif

  return paths;
}


#if 0
static void
check_for_descending_qend (int prev_qend, Univcoord_T prev_univdiagonal, List_T qstart_diagonals) {
  List_T p;
  Univdiag_T diagonal;

  for (p = qstart_diagonals; p != NULL; p = List_next(p)) {
    diagonal = (Univdiag_T) List_head(qstart_diagonals);
    if (diagonal->qend > prev_qend) {
      abort();
    } else if (diagonal->qend == prev_qend && diagonal->univdiagonal > prev_univdiagonal) {
      abort();
    }
    prev_qend = diagonal->qend;
    prev_univdiagonal = diagonal->univdiagonal;
  }
  return;
}
#endif

#if 0
static void
check_for_ascending_qstart (int prev_qstart, Univcoord_T prev_univdiagonal, List_T qend_diagonals) {
  List_T p;
  Univdiag_T diagonal;

  for (p = qend_diagonals; p != NULL; p = List_next(p)) {
    diagonal = (Univdiag_T) List_head(qend_diagonals);
    if (diagonal->qstart < prev_qstart) {
      abort();
    } else if (diagonal->qstart == prev_qstart && diagonal->univdiagonal < prev_univdiagonal) {
      abort();
    }
    prev_qstart = diagonal->qstart;
    prev_univdiagonal = diagonal->univdiagonal;
  }
  return;
}
#endif
  

/* Recursively adds diagonals to the start of a path, using either knownsplicing or localdb */
/* Note: is is important to trim ends before calling Localdb_get,
   because the presence of a splice site indicates the boundary point
   for searching the distal end */

/* Either returns NULL, which means caller should use the given path (or a copy)
   as the result, or returns newpaths, which of which is different
   from path, where the caller needs to free path, if desired */
static void
compute_qstart_local (List_T *unextended_paths, List_T *complete_paths,
		      int depth, Path_T path, char *queryptr, int querylength,
		      int *mismatch_positions_alloc, Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
		      int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
		      Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,
		      Indelinfo_T indelinfo, Spliceinfo_T spliceinfo,
		      Knownsplicing_T knownsplicing, Knownindels_T knownindels, Compress_T query_compress, 
		      Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
		      Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		      Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
		      Vectorpool_T vectorpool, Hitlistpool_T hitlistpool, Spliceendsgen_T spliceendsgen,
		      int max_insertionlen, int max_deletionlen, int localdb_nmismatches_allowed,
		      Chrpos_T overall_end_distance, bool plusp, int genestrand,
		      int try_sensedir, bool innerp, bool salvagep, Pass_T pass) {
  List_T newpaths = NULL, p;
  T splice_path, end_path, newpath, parent;
  Univcoord_T univdiagonal;
  int qstart, pos3, exon_origin, indel_pos, trimpos, adj;
  int nmismatches_i;

  bool splice5p;
  Splicetype_T splicetype5;
  int nspliceends, i, j;
  Spliceends_T spliceends;
  int *trim_qstarts, nosplice_trimpos, medial_splice_trimpos_0;
  double *ambig_probs_5, ambig_prob_5, *distal_probs;
  Univcoord_T *distal_splice_positions;
  /* int *medial_nmismatches; */
  int *distal_nmismatches, nosplice_nmismatches, medial_splice_nmismatches_0, pos5_nmismatches;
  int found_sensedir;


  debug13(printf("Entering compute_qstart_local, salvage %d, at depth %d with path:\n",salvagep,depth));
  debug13(Path_print(path));
  debug13(printf("\n"));

  Path_expect_fwd(path);

  if (path->qstart_alts != NULL) {
    /* Not possible to add localdb because of the ambiguity */
    debug13(printf("compute_qstart_local is complete because of qstart_alts\n"));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(1) Putting into complete qstart paths: ")); debug20(Path_print(newpath));
    *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_fwd(newpath)
				   hitlistpool_trace(__FILE__,__LINE__));
    return;

  } else if ((qstart = Intlist_head(path->endpoints)) == 0) {
    /* Already at start */
    debug13(printf("compute_qstart_local is complete because of qstart == 0\n"));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(2) Putting into complete qstart paths: ")); debug20(Path_print(newpath));
    *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_fwd(newpath)
				   hitlistpool_trace(__FILE__,__LINE__));
    return;

  } else if (depth > MAX_DEPTH_LOCAL) {
    /* Too much recursive depth */
    debug13(printf("compute_qstart_local is unextended because of depth %d\n",depth));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(3) Putting into unextended qstart paths: ")); debug20(Path_print(newpath));
    assert(newpath->sensedir == try_sensedir);
    *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) Path_expect_fwd(newpath)
				     hitlistpool_trace(__FILE__,__LINE__));
    return;

  } else {
    /* Attempt to extend */

    /* pos3 is the end of the current segment.  qstart is the
       approximate start of the current segment.  pos5 (0) to qstart
       is where we look for a new segment. */
    pos3 = Intlist_head(Intlist_next(path->endpoints));
    univdiagonal = Univcoordlist_head(path->univdiagonals);
    /* left = univdiagonal - (Univcoord_T) querylength; */
    
    /* Unless try_sensedir is SENSE_NULL, found_sensedir will be the same as try_sensedir */
    exon_origin = Path_exon_origin(path);
    debug13(printf("(X) Calling Spliceends_trimmed_qstarts with univdiagonal %u, pos3 %d, exon_origin %d\n",
		   univdiagonal,pos3,exon_origin));
    nspliceends = Spliceends_trimmed_qstarts(&spliceends,&nosplice_trimpos,&medial_splice_trimpos_0,
					     &pos5_nmismatches,&nosplice_nmismatches,&medial_splice_nmismatches_0,
					     &splice5p,&splicetype5,&ambig_prob_5,
					     try_sensedir,univdiagonal,querylength,
					     /*qstart:0,*//*qend*/pos3,exon_origin,chrnum,chroffset,
					     plusp,genestrand,localdb_nmismatches_allowed,innerp,salvagep,
					     mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
					     streamspace_max_alloc,streamspace_alloc,
					     streamptr_alloc,streamsize_alloc,mergeinfo,
					     knownsplicing,spliceendsgen,query_compress,queryptr,
					     genomebits,genomebits_alt,novelsplicingp);
    debug13(printf("Spliceends_trimmed_qstarts returning %d spliceends, nosplice %d (%d nmismatches), medial splice %d (%d nmismatches), pos5_nmismatches %d\n",
		   nspliceends,nosplice_trimpos,nosplice_nmismatches,medial_splice_trimpos_0,medial_splice_nmismatches_0,pos5_nmismatches));
    
    if (nspliceends == 0) {
      debug13(printf("No trimming\n"));
      
    } else if (spliceends != NULL) {
      found_sensedir = spliceends->sensedir;
      trim_qstarts = spliceends->trimends;
      ambig_probs_5 = spliceends->ambig_probs;
      /* medial_nmismatches = spliceends->medial_nmismatches; */
      distal_nmismatches = spliceends->distal_nmismatches;
      distal_splice_positions = spliceends->partners; /* From knownsplicing */
      distal_probs = spliceends->distal_probs;
#ifdef DEBUG13
      printf("Got %d spliceends\n",nspliceends);
      for (int i = 0; i < nspliceends; i++) {
	printf("splice_qpos %d => partner %u, mismatches %d, prob %f\n",
	       trim_qstarts[i],distal_splice_positions[i],distal_nmismatches[i],distal_probs[i]);
      }
#endif
      
      i = 0;
      while (i < nspliceends) {
	ambig_prob_5 = ambig_probs_5[i];
	qstart = trim_qstarts[i]; /* was low_qstart */
	j = i + 1;
	while (j < nspliceends && trim_qstarts[j] == qstart) {
	  j++;
	}
	
	/* Handle a cluster of solutions for qstart */
	debug13(printf("Splice qpos: %d, medial prob %f\n",qstart,ambig_prob_5));
	newpaths = List_append(newpaths,
			       multiadd_splice_qstarts(path,univdiagonal,
						       /*common_splice_qpos*/qstart,/*common_splice_prob*/ambig_prob_5,
						       &(distal_splice_positions[i]),&(distal_nmismatches[i]),
						       &(distal_probs[i]),/*npartners*/(j - i),
						       chrnum,chroffset,querylength,
						       query_compress,queryptr,plusp,genestrand,
						       knownsplicing,spliceendsgen,mismatch_positions_alloc,
						       intlistpool,univcoordlistpool,listpool,
						       hitlistpool,pathpool,vectorpool,found_sensedir));
	i = j;
      }
      
      Spliceendsgen_return(spliceendsgen,&spliceends);
    }

    if (newpaths == NULL) {
      /* Splice end without partner, or an end indel */
      /* Try start indel */
      debug13(printf("Path before trying start indel:\n"));
      debug13(Path_print(path));
      debug13(printf("\n"));
      
      /* Computed above */
      /* pos3 = Intlist_head(Intlist_next(path->endpoints)); */
      /* univdiagonal = Univcoordlist_head(path->univdiagonals); */
      /* left = univdiagonal - (Univcoord_T) querylength; */
      
#ifdef DEBUG13
      if (nosplice_trimpos != 0) {
	printf("(X) Calling Genomebits_indel_solve_low with %d..%d\n",0,nosplice_trimpos);
      }
#endif
      
      if (nosplice_trimpos == 0) {
	/* Already extended to the start */
	debug13(printf("Actually, not solving for indel because nosplice_trimpos is %d\n",nosplice_trimpos));
	
      } else if (knownindels != NULL &&
		 (adj = Knownindels_find_highest(&indel_pos,knownindels,univdiagonal,querylength,
						 /*pos5*/0,/*pos3*/nosplice_trimpos+1)) != 0) {
	debug13(printf("Knownindels succeeeds with with adj %d and indel_pos %d\n",adj,indel_pos));
	newpath = attach_indel_qstart_simple(adj,path,indel_pos,univdiagonal,querylength,try_sensedir,
					     plusp,genestrand,mismatch_positions_alloc,
					     knownsplicing,spliceendsgen,query_compress,queryptr,
					     genomebits,genomebits_alt,chrnum,chroffset,novelsplicingp,
					     intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	newpaths = Hitlist_push(newpaths,hitlistpool,(void *) Path_expect_fwd(newpath)
				hitlistpool_trace(__FILE__,__LINE__));
	
      } else if ((adj = Genomebits_indel_solve_low(&trimpos,&nmismatches_i,
						   univdiagonal,querylength,/*pos5*/0,/*pos3*/nosplice_trimpos,
						   query_compress,mismatch_positions_alloc,
						   genomebits,genomebits_alt,plusp,genestrand)) != 0) {
	debug13(printf("Genomebits_indel_solve_low succeeds with adj %d and %d mismatches\n",adj,nmismatches_i));
#if 0
	/* Code below is specific to solve_low, because insertion changes qend, but not qstart */
	indel_pos = (adj > 0) ? nosplice_trimpos : nosplice_trimpos + adj;
#endif
	
	/* Subtract adj to get low diagonal, but add adj to get high diagonal */
	if ((newpath = attach_indel_qstart(path,/*low_diagonal*/univdiagonal - adj,/*low_qstart*/trimpos,
					   chroffset,chrhigh,querylength,indelinfo,
					   query_compress,plusp,genestrand,
					   max_insertionlen,max_deletionlen,
					   intlistpool,univcoordlistpool,listpool,pathpool,vectorpool)) != NULL) {
	  newpaths = Hitlist_push(newpaths,hitlistpool,(void *) Path_expect_fwd(newpath)
				  hitlistpool_trace(__FILE__,__LINE__));
	}
	
      } else {
	debug13(printf("Genomebits_indel_solve_low fails\n"));
      }
    }
    /* Done with attempt to extend */
      
    if (newpaths == NULL) {
      /* Terminate this path with splice end and/or mismatches to the end.  No recursion. */

      /* Splice end */
      splice_path = (T) NULL;
      if (medial_splice_trimpos_0 == -1) {
	/* No splice end */
      } else if (0 && medial_splice_trimpos_0 == Intlist_head(path->endpoints)) {
	/* No change, but want to set splice5p so this path is considered complete and undergoes repair */
      } else {
	/* Change endpoint to the splice trimpos */
	/* assert(nspliceends == 1); */
	splice_path = Path_copy(path,intlistpool,univcoordlistpool,listpool,
				pathpool,vectorpool,transcriptpool);

	debug13(printf("(1) Changing endpoint from %d",Intlist_head(path->endpoints)));
	if (medial_splice_trimpos_0 > Intlist_head(path->endpoints) && Intlist_head(path->nmismatches) == 0) {
	  /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
	  Intlist_head_set(splice_path->endpoints,medial_splice_trimpos_0);
	} else {
	  Intlist_head_set(splice_path->endpoints,medial_splice_trimpos_0);
	  Intlist_head_set(splice_path->nmismatches,medial_splice_nmismatches_0);
	  Intlist_head_set(splice_path->ref_nmismatches,medial_splice_nmismatches_0);
	}
	splice_path->splice5p = splice5p;
	splice_path->splicetype5 = splicetype5;
	splice_path->ambig_prob_5 = ambig_prob_5;
	debug13(printf(" to splice end %d (splice5p %d) with %d mismatches\n",
		       medial_splice_trimpos_0,splice5p,Intlist_head(splice_path->nmismatches)));
	debug13(Path_print(splice_path));

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || Intlist_head(splice_path->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("splice path from compute_qstart_local is reasonably complete because of qstart %d => putting into complete\n",
			 Intlist_head(splice_path->endpoints)));
	  debug13(Path_print(splice_path));
	  debug20(printf("(4) Putting into complete qstart paths: ")); debug20(Path_print(splice_path));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_fwd(splice_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {	
	  debug13(printf("splice path from compute_qstart_local is unextended because of qstart %d => putting into unextended\n",
			 Intlist_head(splice_path->endpoints)));
	  debug20(printf("(5) Putting into unextended qstart paths: ")); debug20(Path_print(splice_path));
	  assert(splice_path->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) Path_expect_fwd(splice_path)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }

      /* Extend to end */
      end_path = (T) NULL;
      if (nosplice_trimpos == Intlist_head(path->endpoints)) {
	/* No change */
      } else if (nosplice_trimpos == Intlist_second_value(path->endpoints)) {
	debug13(printf("Segment is not great, since nosplice_trimpos erases segment, so not trimming\n"));
      
      } else if (Univcoordlist_head(path->univdiagonals) - querylength + nosplice_trimpos >= chrhigh) {
	debug13(printf("Attempt to trim beyond end of chromosome (%u > %u), so not trimming\n",
		       Univcoordlist_head(path->univdiagonals) - querylength + trimpos,chrhigh));
      } else {
	/* Change endpoint to the non-splice trimpos */
	end_path = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			     pathpool,vectorpool,transcriptpool);

	debug13(printf("(2) Changing endpoint from %d",Intlist_head(path->endpoints)));
	if (nosplice_trimpos > Intlist_head(path->endpoints) && Intlist_head(path->nmismatches) == 0) {
	  /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
	  Intlist_head_set(end_path->endpoints,nosplice_trimpos);
	} else {
	  Intlist_head_set(end_path->endpoints,nosplice_trimpos);
	  Intlist_head_set(end_path->nmismatches,nosplice_nmismatches);
	  Intlist_head_set(end_path->ref_nmismatches,nosplice_nmismatches);
	}
	end_path->splice5p = false;
	end_path->splicetype5 = NO_SPLICE;
	end_path->ambig_prob_5 = 0.0;
	debug13(printf(" to nosplice end %d (splice5p %d) with %d mismatches\n",
		       nosplice_trimpos,splice5p,Intlist_head(end_path->endpoints)));
	debug13(Path_print(end_path));

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || Intlist_head(end_path->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("splice path from compute_qstart_local is reasonably complete because of qstart %d => putting into complete\n",
			 Intlist_head(end_path->endpoints)));
	  debug13(Path_print(end_path));
	  debug20(printf("(4) Putting into complete qstart paths: ")); debug20(Path_print(end_path));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_fwd(end_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {	
	  debug13(printf("splice path from compute_qstart_local is unextended because of qstart %d => putting into unextended\n",
			 Intlist_head(end_path->endpoints)));
	  debug20(printf("(5) Putting into unextended qstart paths: ")); debug20(Path_print(end_path));
	  assert(end_path->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) Path_expect_fwd(end_path)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }

      if (splice_path == NULL && end_path == NULL) {
	newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			    pathpool,vectorpool,transcriptpool);

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || Intlist_head(newpath->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("splice path from compute_qstart_local is reasonably complete because of qstart %d => putting into complete\n",
			 Intlist_head(newpath->endpoints)));
	  debug13(Path_print(newpath));
	  debug20(printf("(4) Putting into complete qstart paths: ")); debug20(Path_print(newpath));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_fwd(newpath)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {	
	  debug13(printf("splice path from compute_qstart_local is unextended because of qstart %d => putting into unextended\n",
			 Intlist_head(newpath->endpoints)));
	  debug20(printf("(5) Putting into unextended qstart paths: ")); debug20(Path_print(newpath));
	  assert(newpath->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,(void *) Path_expect_fwd(newpath)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }

      return;

    } else {
      /* Extensions were added, so recurse */
      for (p = newpaths; p != NULL; p = List_next(p)) {
	parent = (T) List_head(p);
	compute_qstart_local(&(*unextended_paths),&(*complete_paths),depth+1,parent,queryptr,querylength,
			     mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			     streamspace_max_alloc,streamspace_alloc,
			     streamptr_alloc,streamsize_alloc,mergeinfo,
			     indelinfo,spliceinfo,knownsplicing,knownindels,
			     query_compress,chrnum,chroffset,chrhigh,intlistpool,
			     univcoordlistpool,listpool,pathpool,transcriptpool,
			     vectorpool,hitlistpool,spliceendsgen,
			     max_insertionlen,max_deletionlen,localdb_nmismatches_allowed,
			     overall_end_distance,plusp,genestrand,
			     try_sensedir,innerp,salvagep,pass);
	Path_free(&parent,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
      return;
    }
  }
}


/* Recursively adds diagonals to the end of a path */
/* Either returns NULL, which means caller should use the given path (or a copy)
   as the result, or returns newpaths, which of which is different
   from path, where the caller needs to free path, if desired */
static void
compute_qend_local (List_T *unextended_paths, List_T *complete_paths,
		    int depth, T path, char *queryptr, int querylength,
		    int *mismatch_positions_alloc, Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
		    int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
		    Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,
		    Indelinfo_T indelinfo, Spliceinfo_T spliceinfo,
		    Knownsplicing_T knownsplicing, Knownindels_T knownindels, Compress_T query_compress, 
		    Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
		    Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		    Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
		    Vectorpool_T vectorpool, Hitlistpool_T hitlistpool, Spliceendsgen_T spliceendsgen,
		    int max_insertionlen, int max_deletionlen, int localdb_nmismatches_allowed,
		    Chrpos_T overall_end_distance, bool plusp, int genestrand,
		    int try_sensedir, bool innerp, bool salvagep, Pass_T pass) {
  List_T newpaths = NULL, p;
  T splice_path, end_path, newpath, parent;
  Univcoord_T univdiagonal;
  int qend, pos5, exon_origin, indel_pos, trimpos, adj;
  int nmismatches_j;

  bool splice3p;
  Splicetype_T splicetype3;
  int nspliceends, i, j;
  Spliceends_T spliceends;
  int *trim_qends, nosplice_trimpos, medial_splice_trimpos_0; /* Most proximal medial_splice_trimpos */
  double *ambig_probs_3, ambig_prob_3, *distal_probs;
  Univcoord_T *distal_splice_positions;
  /* int *medial_nmismatches; */
  int *distal_nmismatches, nosplice_nmismatches, medial_splice_nmismatches_0, pos3_nmismatches;
  int found_sensedir;


  debug13(printf("Entering compute_qend_local, salvage %d, at depth %d with path:\n",salvagep,depth));
  debug13(Path_print(path));
  debug13(printf("\n"));

  Path_expect_rev(path);

  if (path->qend_alts != NULL) {
    /* Not possible to add localdb because of the ambiguity */
    debug13(printf("compute_qstart_local is complete because of qend_alts\n"));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(6) Putting into complete qend paths: ")); debug20(Path_print(newpath));
    *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_rev(newpath)
				   hitlistpool_trace(__FILE__,__LINE__));
    return;
	
  } else if ((qend = Intlist_head(path->endpoints)) == querylength) {
    /* Already at end */
    debug13(printf("compute_qend_local is complete because of qend == querylength\n"));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(7) Putting into complete qend paths: ")); debug20(Path_print(newpath));
    *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_rev(newpath)
				   hitlistpool_trace(__FILE__,__LINE__));
    return;

  } else if (depth > MAX_DEPTH_LOCAL) {
    /* Too much recursive depth */
    debug13(printf("compute_qend_local is unextended because of depth %d\n",depth));
    newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			pathpool,vectorpool,transcriptpool);
    debug20(printf("(8) Putting into unextended qend paths: ")); debug20(Path_print(newpath));
    assert(newpath->sensedir == try_sensedir);
    *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
				     (void *) Path_reverse(newpath,/*expect_fwd_p*/true)
				     hitlistpool_trace(__FILE__,__LINE__));
  } else {
    /* Attempt to extend */

    /* pos5 is the start of the current segment.  qend is the
       approximate end of the current segment.  qend to pos3
       (querylength) is where we look for a new segment. */
    pos5 = Intlist_head(Intlist_next(path->endpoints));
    if (path->junctions != NULL) {
      pos5 += Junction_ninserts((Junction_T) List_head(path->junctions));
    }
    univdiagonal = Univcoordlist_head(path->univdiagonals);
    /* left = univdiagonal - (Univcoord_T) querylength; */

    /* Unless try_sensedir is SENSE_NULL, found_sensedir will be the same as try_sensedir */
    exon_origin = Path_exon_origin(path);
    debug13(printf("(X) Calling Spliceends_trimmed_qends with univdiagonal %u, pos5 %d, exon_origin %d\n",
		   univdiagonal,pos5,exon_origin));
    nspliceends = Spliceends_trimmed_qends(&spliceends,&nosplice_trimpos,&medial_splice_trimpos_0,
					   &pos3_nmismatches,&nosplice_nmismatches,&medial_splice_nmismatches_0,
					   &splice3p,&splicetype3,&ambig_prob_3,
					   try_sensedir,univdiagonal,querylength,
					   /*qstart*/pos5,/*qend:querylength,*/exon_origin,chrnum,chroffset,chrhigh,
					   plusp,genestrand,localdb_nmismatches_allowed,innerp,salvagep,
					   mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
					   streamspace_max_alloc,streamspace_alloc,
					   streamptr_alloc,streamsize_alloc,mergeinfo,
					   knownsplicing,spliceendsgen,query_compress,queryptr,
					   genomebits,genomebits_alt,novelsplicingp);
    debug13(printf("Spliceends_trimmed_qends returning %d spliceends, nosplice %d (%d nmismatches), medial_splice %d (%d nmismatches), pos3_nmismatches %d\n",
		   nspliceends,nosplice_trimpos,nosplice_nmismatches,medial_splice_trimpos_0,medial_splice_nmismatches_0,pos3_nmismatches));
    
    if (nspliceends == 0) {
      /* No trimming.  Means that trimpos < pos5, so a bad segment */
      debug13(printf("No trimming\n"));
      
    } else if (spliceends == NULL) {
      debug13(printf("No partners found\n"));
      
    } else {
      found_sensedir = spliceends->sensedir;
      trim_qends = spliceends->trimends;
      ambig_probs_3 = spliceends->ambig_probs;
      /* medial_nmismatches = spliceends->medial_nmismatches; */
      distal_nmismatches = spliceends->distal_nmismatches;
      distal_splice_positions = spliceends->partners; /* From knownsplicing */
      distal_probs = spliceends->distal_probs;
#ifdef DEBUG13
      printf("Got %d spliceends\n",nspliceends);
      for (int i = 0; i < nspliceends; i++) {
	printf("splice_qpos %d => partner %u, mismatches %d, prob %f\n",
	       trim_qends[i],distal_splice_positions[i],distal_nmismatches[i],distal_probs[i]);
      }
#endif

      i = 0;
      while (i < nspliceends) {
	ambig_prob_3 = ambig_probs_3[i];
	qend = trim_qends[i]; /* was high_qend */
	j = i + 1;
	while (j < nspliceends && trim_qends[j] == qend) {
	  j++;
	}
	
	/* Handle a cluster of solutions for qend */
	debug13(printf("Splice qpos: %d, medial prob %f\n",qend,ambig_prob_3));
	newpaths = List_append(newpaths,
			       multiadd_splice_qends(path,univdiagonal,
						     /*common_splice_qpos*/qend,/*common_splice_prob*/ambig_prob_3,
						     &(distal_splice_positions[i]),&(distal_nmismatches)[i],
						     &(distal_probs[i]),/*npartners*/(j - i),
						     chrnum,chroffset,chrhigh,querylength,
						     query_compress,queryptr,plusp,genestrand,
						     knownsplicing,spliceendsgen,mismatch_positions_alloc,
						     intlistpool,univcoordlistpool,listpool,
						     hitlistpool,pathpool,vectorpool,found_sensedir));
	i = j;
      }
      
      Spliceendsgen_return(spliceendsgen,&spliceends);
    }

    if (newpaths == NULL) {
      /* Splice end without partner, or an end indel */
      /* Try end indel */
      debug13(printf("Path before trying end indel:\n"));
      debug13(Path_print(path));
      debug13(printf("\n"));

      /* Computed above */
      /* pos5 = Intlist_head(Intlist_next(path->endpoints)); */
      /* univdiagonal = Univcoordlist_head(path->univdiagonals); */
      /* left = univdiagonal - (Univcoord_T) querylength; */
      
#ifdef DEBUG13
      if (nosplice_trimpos != querylength) {
	printf("(X) Calling Genomebits_indel_solve_high with %d..%d\n",nosplice_trimpos,querylength);
      }
#endif
  
      if (nosplice_trimpos == querylength) {
	/* Already extended to the end */
	debug13(printf("Actually, not solving for indel because nosplice_trimpos is %d\n",nosplice_trimpos));
	
      } else if (knownindels != NULL &&
		 (adj = Knownindels_find_lowest(&indel_pos,knownindels,univdiagonal,querylength,
						/*pos5*/nosplice_trimpos-1,/*pos3*/querylength)) != 0) {
	debug13(printf("Knownindels succeeeds with with adj %d and indel_pos %d\n",adj,indel_pos));
	newpath = attach_indel_qend_simple(adj,path,indel_pos,univdiagonal,querylength,try_sensedir,
					   plusp,genestrand,mismatch_positions_alloc,
					   knownsplicing,spliceendsgen,query_compress,queryptr,
					   genomebits,genomebits_alt,chrnum,chroffset,chrhigh,novelsplicingp,
					   intlistpool,univcoordlistpool,listpool,pathpool,vectorpool);
	newpaths = Hitlist_push(newpaths,hitlistpool,(void *) Path_expect_rev(newpath)
				hitlistpool_trace(__FILE__,__LINE__));
	
      } else if ((adj = Genomebits_indel_solve_high(&trimpos,&nmismatches_j,
						    univdiagonal,querylength,/*pos5*/nosplice_trimpos,/*pos3*/querylength,
						    query_compress,mismatch_positions_alloc,
						    genomebits,genomebits_alt,plusp,genestrand)) != 0) {
	debug13(printf("Genomebits_indel_solve_high succeeds with adj %d and %d mismatches => trimpos %d\n",
		       adj,nmismatches_j,trimpos));
#if 0
	/* Code below is specific to solve_high, because insertion changes qend, but not qstart */
	indel_pos = nosplice_trimpos;
#endif

	/* Subtract adj to get low diagonal, but add adj to get high diagonal */
	if ((newpath = attach_indel_qend(path,/*high_diagonal*/univdiagonal + adj,/*high_qend*/trimpos,
					 chrhigh,querylength,indelinfo,
					 query_compress,plusp,genestrand,
					 max_insertionlen,max_deletionlen,
					 intlistpool,univcoordlistpool,listpool,pathpool,vectorpool)) != NULL) {
	  newpaths = Hitlist_push(newpaths,hitlistpool,(void *) Path_expect_rev(newpath)
				  hitlistpool_trace(__FILE__,__LINE__));
	}
	
      } else {
	debug13(printf("Genomebits_indel_solve_high fails\n"));
      }
    }
    /* Done with attempt to extend */
    
    if (newpaths == NULL) {
      /* Terminate this path with splice end and/or mismatches to the end.  No recursion. */

      /* Splice end */
      splice_path = (T) NULL;
      if (medial_splice_trimpos_0 == -1) {
	/* No splice end */
      } else if (0 && medial_splice_trimpos_0 == Intlist_head(path->endpoints)) {
	/* No change, but want to set splice3p so this path is considered complete and undergoes repair */
      } else if (path->junctions != NULL &&
		 Intlist_head(Intlist_next(path->endpoints)) +
		 Junction_ninserts((Junction_T) List_head(path->junctions)) >= medial_splice_trimpos_0) {
	debug13(printf("(3) End indel %d + ins:%d vs changing endpoint from %d to splice end %d\n",
		       Intlist_head(Intlist_next(path->endpoints)),Junction_ninserts((Junction_T) List_head(path->junctions)),
		       Intlist_head(path->endpoints),medial_splice_trimpos_0));
      } else {
	/* Change endpoint to the splice trimpos */
	/* assert(nspliceends == 1); */
	splice_path = Path_copy(path,intlistpool,univcoordlistpool,listpool,
				pathpool,vectorpool,transcriptpool);
	debug13(printf("(3) Changing endpoint from %d",Intlist_head(path->endpoints)));
	if (medial_splice_trimpos_0 < Intlist_head(path->endpoints) && Intlist_head(path->nmismatches) == 0) {
	  /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
	  Intlist_head_set(splice_path->endpoints,medial_splice_trimpos_0);
	} else {
	  Intlist_head_set(splice_path->endpoints,medial_splice_trimpos_0);
	  Intlist_head_set(splice_path->nmismatches,medial_splice_nmismatches_0);
	  Intlist_head_set(splice_path->ref_nmismatches,medial_splice_nmismatches_0);
	}
	splice_path->splice3p = splice3p;
	splice_path->splicetype3 = splicetype3;
	splice_path->ambig_prob_3 = ambig_prob_3;
	debug13(printf(" to splice end %d (splice3p %d) with %d mismatches\n",
		       medial_splice_trimpos_0,splice3p,Intlist_head(splice_path->nmismatches)));
	debug13(Path_print(splice_path));

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || querylength - Intlist_head(splice_path->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("compute_qend_local is reasonably complete because of qend %d => putting into complete\n",
			 Intlist_head(splice_path->endpoints)));
	  debug13(Path_print(splice_path));
	  debug20(printf("(9) Putting into complete qend paths: ")); debug20(Path_print(splice_path));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_rev(splice_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {
	  debug13(printf("compute_qend_local is unextended because of qend %d => putting into unextended\n",
			 Intlist_head(splice_path->endpoints)));
	  debug20(printf("(10) Putting into unextended qend paths: ")); debug20(Path_print(splice_path));
	  assert(splice_path->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
					   (void *) Path_reverse(splice_path,/*expect_fwd_p*/true)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }
	
      /* Extend to end */
      end_path = (T) NULL;
      if (nosplice_trimpos == Intlist_head(path->endpoints)) {
	/* No change */
      } else if (nosplice_trimpos == Intlist_second_value(path->endpoints)) {
	debug13(printf("Segment is not great, since nosplice_trimpos erases segment, so not trimming\n"));
	
      } else if (Univcoordlist_head(path->univdiagonals) - querylength + nosplice_trimpos < chroffset) {
	debug13(printf("Attempt to trim beyond start of chromosome (%u < %u), so not trimming\n",
		       Univcoordlist_head(path->univdiagonals) - querylength + trimpos,chroffset));

      } else if (path->junctions != NULL &&
		 Intlist_head(Intlist_next(path->endpoints)) +
		 Junction_ninserts((Junction_T) List_head(path->junctions)) >= nosplice_trimpos) {
	debug13(printf("(4) End indel %d + ins:%d vs changing endpoint from %d to splice end %d\n",
		       Intlist_head(Intlist_next(path->endpoints)),Junction_ninserts((Junction_T) List_head(path->junctions)),
		       Intlist_head(path->endpoints),nosplice_trimpos));
      } else {
	/* Change endpoint to the non-splice trimpos */
	end_path = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			     pathpool,vectorpool,transcriptpool);

	debug13(printf("(4) Changing endpoint from %d",Intlist_head(path->endpoints)));
	if (nosplice_trimpos < Intlist_head(path->endpoints) && Intlist_head(path->nmismatches) == 0) {
	  /* Shorter segment in region with no nmismatches, so can keep nmismatches being 0 */
	  Intlist_head_set(end_path->endpoints,nosplice_trimpos);
	} else {
	  Intlist_head_set(end_path->endpoints,nosplice_trimpos);
	  Intlist_head_set(end_path->nmismatches,nosplice_nmismatches);
	  Intlist_head_set(end_path->ref_nmismatches,nosplice_nmismatches);
	}
	end_path->splice3p = false;
	end_path->splicetype3 = NO_SPLICE;
	end_path->ambig_prob_3 = 0.0;
	debug13(printf(" to nosplice end %d (splice3p %d) with %d mismatches\n",
		       nosplice_trimpos,splice3p,Intlist_head(end_path->nmismatches)));
	debug13(Path_print(end_path));

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || querylength - Intlist_head(end_path->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("compute_qend_local is reasonably complete because of qend %d => putting into complete\n",
			 Intlist_head(end_path->endpoints)));
	  debug13(Path_print(end_path));
	  debug20(printf("(9) Putting into complete qend paths: ")); debug20(Path_print(end_path));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_rev(end_path)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {
	  debug13(printf("compute_qend_local is unextended because of qend %d => putting into unextended\n",
			 Intlist_head(end_path->endpoints)));
	  debug20(printf("(10) Putting into unextended qend paths: ")); debug20(Path_print(end_path));
	  assert(end_path->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
					   (void *) Path_reverse(end_path,/*expect_fwd_p*/true)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }

      if (splice_path == NULL && end_path == NULL) {
	newpath = Path_copy(path,intlistpool,univcoordlistpool,listpool,
			    pathpool,vectorpool,transcriptpool);

	/* No longer filtering based on 8 bp at ends, which misses some reads and misses the chance to combine qstart and qend */
	if (1 || querylength - Intlist_head(newpath->endpoints) <= 8) {
	  /* Reasonably complete */
	  debug13(printf("compute_qend_local is reasonably complete because of qend %d => putting into complete\n",
			 Intlist_head(newpath->endpoints)));
	  debug13(Path_print(newpath));
	  debug20(printf("(9) Putting into complete qend paths: ")); debug20(Path_print(newpath));
	  *complete_paths = Hitlist_push(*complete_paths,hitlistpool,(void *) Path_expect_rev(newpath)
					 hitlistpool_trace(__FILE__,__LINE__));
	} else {
	  debug13(printf("compute_qend_local is unextended because of qend %d => putting into unextended\n",
			 Intlist_head(newpath->endpoints)));
	  debug20(printf("(10) Putting into unextended qend paths: ")); debug20(Path_print(newpath));
	  assert(newpath->sensedir == try_sensedir);
	  *unextended_paths = Hitlist_push(*unextended_paths,hitlistpool,
					   (void *) Path_reverse(newpath,/*expect_fwd_p*/true)
					   hitlistpool_trace(__FILE__,__LINE__));
	}
      }

      return;

    } else {
      /* Extensions were added, so recurse */
      for (p = newpaths; p != NULL; p = List_next(p)) {
	parent = (T) List_head(p);
	compute_qend_local(&(*unextended_paths),&(*complete_paths),depth+1,parent,queryptr,querylength,
			   mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			   streamspace_max_alloc,streamspace_alloc,
			   streamptr_alloc,streamsize_alloc,mergeinfo,
			   indelinfo,spliceinfo,knownsplicing,knownindels,
			   query_compress,chrnum,chroffset,chrhigh,intlistpool,
			   univcoordlistpool,listpool,pathpool,transcriptpool,
			   vectorpool,hitlistpool,spliceendsgen,
			   max_insertionlen,max_deletionlen,localdb_nmismatches_allowed,
			   overall_end_distance,plusp,genestrand,
			   try_sensedir,innerp,salvagep,pass);
	Path_free(&parent,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
      return;
    }
  }
}


static bool
try_repairs (int *found_score, bool *found_transcriptp,
	     List_T *paths, Path_T path,
	     Compress_T query_compress_fwd, Compress_T query_compress_rev,
	     Shortread_T queryseq, Intlistpool_T intlistpool, Uintlistpool_T uintlistpool,
	     Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
	     Transcriptpool_T transcriptpool, Pathpool_T pathpool,
	     Vectorpool_T vectorpool, Hitlistpool_T hitlistpool) {
  bool repairedp = false;
  T newpath;
  List_T repairs, r;
  Repair_T repair;
  int desired_genestrand;
  Compress_T query_compress;

#if 0
  if (path->sensedir == SENSE_FORWARD) {
    desired_genestrand = (path->plusp == true) ? +1 : -1;
  } else {
    desired_genestrand = (path->plusp == true) ? -1 : +1;
  }
#endif

  if (path->plusp == true) {
    query_compress = query_compress_fwd;
    desired_genestrand = (path->sensedir == SENSE_FORWARD) ? +1 : -1;
  } else {
    query_compress = query_compress_rev;
    desired_genestrand = (path->sensedir == SENSE_FORWARD) ? -1 : +1;
  }

  repairs = Transcript_remap_all(&(*found_transcriptp),
				 &path->transcripts,&path->invalid_transcripts,
				 path->endpoints,path->univdiagonals,path->junctions,
				 queryseq,path->querylength,path->plusp,
				 path->chrnum,path->chroffset,path->chrhigh,
				 uintlistpool,listpool,transcriptpool,desired_genestrand,
				 /*extend_qstart_p*/true,/*extend_qend_p*/true,/*repairp*/true);

  repairedp = false;
  for (r = repairs; r != NULL; r = List_next(r)) {
    repair = (Repair_T) List_head(r);
    if ((newpath = Repair_path(&(*found_score),repair,path,path->sensedir,
			       query_compress,query_compress_fwd,query_compress_rev,
			       intlistpool,univcoordlistpool,listpool,
			       pathpool,vectorpool,transcriptpool)) == NULL) {
      Repair_free(&repair,listpool,transcriptpool,/*free_transcripts_p*/true);
    } else {
      *paths = Hitlist_push(*paths,hitlistpool,(void *) newpath
			    hitlistpool_trace(__FILE__,__LINE__));
      repairedp = true;
      /* Repair transcripts got transferred onto newpath->transcripts */
      Repair_free(&repair,listpool,transcriptpool,/*free_transcripts_p*/false);
    } 
  }

  Listpool_free_list(&repairs,listpool
		     listpool_trace(__FILE__,__LINE__));

  return repairedp;
}


void
Path_solve_from_diagonals (int *found_score, bool *found_transcriptp,
			   List_T *unextended_sense_paths, List_T *unextended_antisense_paths,
			   List_T *sense_paths, List_T *antisense_paths,

			   Univcoord_T middle_diagonal_univdiagonal, int middle_diagonal_qstart, int middle_diagonal_qend,
			   int middle_nmismatches, List_T qend_univdiags, List_T qstart_univdiags,

			   Shortread_T queryseq, char *queryptr, int querylength, int *mismatch_positions_alloc,
			   Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
			   int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
			   Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,

			   Indelinfo_T indelinfo, Spliceinfo_T spliceinfo, Knownsplicing_T knownsplicing, Knownindels_T knownindels,
			   Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
			   Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
			   bool plusp, int genestrand,
			   int max_insertionlen, int max_deletionlen, int localdb_nmismatches_allowed,
			   Chrpos_T overall_end_distance, bool paired_end_p, bool first_read_p,
			   Intlistpool_T intlistpool, Uintlistpool_T uintlistpool, Univcoordlistpool_T univcoordlistpool,
			   Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
			   Vectorpool_T vectorpool, Hitlistpool_T hitlistpool,
			   Spliceendsgen_T spliceendsgen, Method_T method, Pass_T pass) {

  T path, newpath;

  List_T qstart_sense_paths = NULL, qstart_antisense_paths = NULL,
    qend_sense_paths = NULL, qend_antisense_paths = NULL, combined_sense_paths, combined_antisense_paths, p;
  Univdiag_T univdiag;
  bool qstart_innerp, qend_innerp;
  bool sense_completep, antisense_completep;


  debug13(printf("Entered Path_solve_from_diagonals from method %s, first_read_p %d, with middle_diagonal #%d %u %d..%d, %d qstart diagonals, and %d qend diagonals\n",
		 Method_string(method),first_read_p,chrnum,middle_diagonal_univdiagonal - chroffset,middle_diagonal_qstart,middle_diagonal_qend,
		 List_length(qstart_univdiags),List_length(qend_univdiags)));
#ifdef DEBUG13
  printf("Start: first_read_p %d, plusp %d\n",first_read_p,plusp);
  printf("Start: %d complete sense paths\n",List_length(*sense_paths));
  printf("Start: %d complete antisense paths\n",List_length(*antisense_paths));
  printf("Start: %d unextended sense paths\n",List_length(*unextended_sense_paths));
  printf("Start: %d unextended antisense paths\n",List_length(*unextended_antisense_paths));

  for (p = qstart_univdiags; p != NULL; p = List_next(p)) {
    printf("qstart diagonal %u\n",((Univdiag_T) List_head(p))->univdiagonal);
  }
  for (p = qend_univdiags; p != NULL; p = List_next(p)) {
    printf("qend diagonal %u\n",((Univdiag_T) List_head(p))->univdiagonal);
  }
#endif


#if 0
  check_for_descending_qend(middle_diagonal_qend,middle_diagonal_univdiagonal,qstart_diagonals);
  check_for_ascending_qstart(middle_diagonal_qstart,middle_diagonal_univdiagonal,qend_diagonals);
#endif

  if (paired_end_p == false) {
    qstart_innerp = qend_innerp = false;
  } else if (first_read_p == plusp) {
    qstart_innerp = false;
    qend_innerp = true;
  } else {
    qstart_innerp = true;
    qend_innerp = false;
  }


  /* Qstart */
  path = Path_new_for_qstart_extension(middle_diagonal_univdiagonal,middle_diagonal_qstart,middle_diagonal_qend,
				       middle_nmismatches,plusp,genestrand,/*sensedir*/SENSE_FORWARD,querylength,
				       method,chrnum,chroffset,chrhigh,
				       /*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
				       intlistpool,univcoordlistpool,pathpool);

  for (p = qstart_univdiags; p != NULL; p = List_next(p)) {
    univdiag = (Univdiag_T) List_head(p);
    /* Previously checked for a large gap between middle_diagonal_qstart and univdiag->qend */

    if (univdiag->univdiagonal < chroffset + querylength) {
      /* Skip, because univdiagonal is in an earlier chromosome */

    } else if ((newpath = attach_unknown_qstart(path,/*low_univdiagonal*/univdiag->univdiagonal,
						/*low_qstart*/univdiag->qstart,
						chroffset,chrhigh,querylength,
						indelinfo,spliceinfo,knownsplicing,
						query_compress,plusp,genestrand,
						max_insertionlen,max_deletionlen,
						intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,
						vectorpool,/*try_sensedir*/SENSE_FORWARD,
						/*salvagep*/false)) != NULL) {

      compute_qstart_local(&(*unextended_sense_paths),&qstart_sense_paths,
			   /*depth*/0,newpath,queryptr,querylength,
			   mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			   streamspace_max_alloc,streamspace_alloc,
			   streamptr_alloc,streamsize_alloc,mergeinfo,
			   indelinfo,spliceinfo,knownsplicing,knownindels,
			   query_compress,chrnum,chroffset,chrhigh,intlistpool,
			   univcoordlistpool,listpool,pathpool,transcriptpool,
			   vectorpool,hitlistpool,spliceendsgen,
			   max_insertionlen,max_deletionlen,
			   localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			   /*try_sensedir*/SENSE_FORWARD,qstart_innerp,/*salvagep*/false,pass);

      Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
    }
  }

  if (qstart_sense_paths == NULL) {
    /* Try without a qstart_univdiag */
    compute_qstart_local(&(*unextended_sense_paths),&qstart_sense_paths,
			 /*depth*/0,path,queryptr,querylength,
			 mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			 streamspace_max_alloc,streamspace_alloc,
			 streamptr_alloc,streamsize_alloc,mergeinfo,
			 indelinfo,spliceinfo,knownsplicing,knownindels,
			 query_compress,chrnum,chroffset,chrhigh,intlistpool,
			 univcoordlistpool,listpool,pathpool,transcriptpool,
			 vectorpool,hitlistpool,spliceendsgen,
			 max_insertionlen,max_deletionlen,
			 localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			 /*try_sensedir*/SENSE_FORWARD,qstart_innerp,/*salvagep*/false,pass);
  }
  Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);

  if (splicingp == true) {
    path = Path_new_for_qstart_extension(middle_diagonal_univdiagonal,middle_diagonal_qstart,middle_diagonal_qend,
					 middle_nmismatches,plusp,genestrand,/*sensedir*/SENSE_ANTI,querylength,
					 method,chrnum,chroffset,chrhigh,
					 /*splice5p*/false,/*splicetype5*/NO_SPLICE,/*ambig_prob_5*/0.0,
					 intlistpool,univcoordlistpool,pathpool);
    for (p = qstart_univdiags; p != NULL; p = List_next(p)) {
      univdiag = (Univdiag_T) List_head(p);
      /* Previously checked for a large gap between middle_diagonal_qstart and univdiag->qend */

      if (univdiag->univdiagonal < chroffset + querylength) {
	/* Skip, because univdiagonal is in an earlier chromosome */

      } else if ((newpath = attach_unknown_qstart(path,/*low_univdiagonal*/univdiag->univdiagonal,
						  /*low_qstart*/univdiag->qstart,
						  chroffset,chrhigh,querylength,
						  indelinfo,spliceinfo,knownsplicing,
						  query_compress,plusp,genestrand,
						  max_insertionlen,max_deletionlen,
						  intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,
						  vectorpool,/*try_sensedir*/SENSE_ANTI,
						  /*salvagep*/false)) != NULL) {
	compute_qstart_local(&(*unextended_antisense_paths),&qstart_antisense_paths,
			     /*depth*/0,newpath,queryptr,querylength,
			     mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			     streamspace_max_alloc,streamspace_alloc,
			     streamptr_alloc,streamsize_alloc,mergeinfo,
			     indelinfo,spliceinfo,knownsplicing,knownindels,
			     query_compress,chrnum,chroffset,chrhigh,intlistpool,
			     univcoordlistpool,listpool,pathpool,transcriptpool,
			     vectorpool,hitlistpool,spliceendsgen,
			     max_insertionlen,max_deletionlen,
			     localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			     /*try_sensedir*/SENSE_ANTI,qstart_innerp,/*salvagep*/false,pass);
	Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
    }

    if (qstart_antisense_paths == NULL) {
      /* Try without a qstart_univdiag */
      compute_qstart_local(&(*unextended_antisense_paths),&qstart_antisense_paths,
			   /*depth*/0,path,queryptr,querylength,
			   mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			   streamspace_max_alloc,streamspace_alloc,
			   streamptr_alloc,streamsize_alloc,mergeinfo,
			   indelinfo,spliceinfo,knownsplicing,knownindels,
			   query_compress,chrnum,chroffset,chrhigh,intlistpool,
			   univcoordlistpool,listpool,pathpool,transcriptpool,
			   vectorpool,hitlistpool,spliceendsgen,
			   max_insertionlen,max_deletionlen,
			   localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			   /*try_sensedir*/SENSE_ANTI,qstart_innerp,/*salvagep*/false,pass);
    }
    Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
  }


  /* Qend */
  path = Path_new_for_qend_extension(middle_diagonal_univdiagonal,middle_diagonal_qstart,middle_diagonal_qend,
				     middle_nmismatches,plusp,genestrand,/*sensedir*/SENSE_FORWARD,querylength,
				     method,chrnum,chroffset,chrhigh,
				     /*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
				     intlistpool,univcoordlistpool,pathpool);

  for (p = qend_univdiags; p != NULL; p = List_next(p)) {
    univdiag = (Univdiag_T) List_head(p);
    /* Previously checked for a large gap between middle_diagonal_qend and univdiag->qstart */

    if (univdiag->univdiagonal >= chrhigh) {
      /* Skip, because univdiagonal is in a later chromosome */
    
    } else if ((newpath = attach_unknown_qend(path,/*high_univdiagonal*/univdiag->univdiagonal,
					      /*high_qstart*/univdiag->qstart,/*high_qend*/univdiag->qend,
					      chroffset,chrhigh,querylength,
					      indelinfo,spliceinfo,knownsplicing,
					      query_compress,plusp,genestrand,
					      max_insertionlen,max_deletionlen,
					      intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,
					      vectorpool,/*try_sensedir*/SENSE_FORWARD,
					      /*salvagep*/false)) != NULL) {

      compute_qend_local(&(*unextended_sense_paths),&qend_sense_paths,
			 /*depth*/0,newpath,queryptr,querylength,
			 mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			 streamspace_max_alloc,streamspace_alloc,
			 streamptr_alloc,streamsize_alloc,mergeinfo,
			 indelinfo,spliceinfo,knownsplicing,knownindels,
			 query_compress,chrnum,chroffset,chrhigh,intlistpool,
			 univcoordlistpool,listpool,pathpool,transcriptpool,
			 vectorpool,hitlistpool,spliceendsgen,
			 max_insertionlen,max_deletionlen,
			 localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			 /*try_sensedir*/SENSE_FORWARD,qend_innerp,/*salvagep*/false,pass);

      Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
    }
  }
      
  if (qend_sense_paths == NULL) {
    /* Try without a qend_univdiag */
    compute_qend_local(&(*unextended_sense_paths),&qend_sense_paths,
		       /*depth*/0,path,queryptr,querylength,
		       mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
		       streamspace_max_alloc,streamspace_alloc,
		       streamptr_alloc,streamsize_alloc,mergeinfo,
		       indelinfo,spliceinfo,knownsplicing,knownindels,
		       query_compress,chrnum,chroffset,chrhigh,intlistpool,
		       univcoordlistpool,listpool,pathpool,transcriptpool,
		       vectorpool,hitlistpool,spliceendsgen,
		       max_insertionlen,max_deletionlen,
		       localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
		       /*try_sensedir*/SENSE_FORWARD,qend_innerp,/*salvagep*/false,pass);
  }
  Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);

  if (splicingp == true) {
    path = Path_new_for_qend_extension(middle_diagonal_univdiagonal,middle_diagonal_qstart,middle_diagonal_qend,
				       middle_nmismatches,plusp,genestrand,/*sensedir*/SENSE_ANTI,querylength,
				       method,chrnum,chroffset,chrhigh,
				       /*splice3p*/false,/*splicetype3*/NO_SPLICE,/*ambig_prob_3*/0.0,
				       intlistpool,univcoordlistpool,pathpool);
    for (p = qend_univdiags; p != NULL; p = List_next(p)) {
      univdiag = (Univdiag_T) List_head(p);
      /* Previously checked for a large gap between middle_diagonal_qend and univdiag->qstart */

      if (univdiag->univdiagonal >= chrhigh) {
	/* Skip, because univdiagonal is in a later chromosome */
    
      } else if ((newpath = attach_unknown_qend(path,/*high_univdiagonal*/univdiag->univdiagonal,
						/*high_qstart*/univdiag->qstart,/*high_qend*/univdiag->qend,
						chroffset,chrhigh,querylength,
						indelinfo,spliceinfo,knownsplicing,
						query_compress,plusp,genestrand,
						max_insertionlen,max_deletionlen,
						intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,
						vectorpool,/*try_sensedir*/SENSE_ANTI,
						/*salvagep*/false)) != NULL) {
	compute_qend_local(&(*unextended_antisense_paths),&qend_antisense_paths,
			   /*depth*/0,newpath,queryptr,querylength,
			   mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			   streamspace_max_alloc,streamspace_alloc,
			   streamptr_alloc,streamsize_alloc,mergeinfo,
			   indelinfo,spliceinfo,knownsplicing,knownindels,
			   query_compress,chrnum,chroffset,chrhigh,intlistpool,
			   univcoordlistpool,listpool,pathpool,transcriptpool,
			   vectorpool,hitlistpool,spliceendsgen,
			   max_insertionlen,max_deletionlen,
			   localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			   /*try_sensedir*/SENSE_ANTI,qend_innerp,/*salvagep*/false,pass);
	Path_free(&newpath,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
    }

    if (qend_antisense_paths == NULL) {
      /* Try without a qend_univdiag */
      compute_qend_local(&(*unextended_antisense_paths),&qend_antisense_paths,
			 /*depth*/0,path,queryptr,querylength,
			 mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
			 streamspace_max_alloc,streamspace_alloc,
			 streamptr_alloc,streamsize_alloc,mergeinfo,
			 indelinfo,spliceinfo,knownsplicing,knownindels,
			 query_compress,chrnum,chroffset,chrhigh,intlistpool,
			 univcoordlistpool,listpool,pathpool,transcriptpool,
			 vectorpool,hitlistpool,spliceendsgen,
			 max_insertionlen,max_deletionlen,
			 localdb_nmismatches_allowed,overall_end_distance,plusp,genestrand,
			 /*try_sensedir*/SENSE_ANTI,qend_innerp,/*salvagep*/false,pass);
    }
    Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
  }

  /* Qstart sense.  Also handles the non-splicing case. */
#ifdef DEBUG13
  for (p = qstart_sense_paths; p != NULL; p = List_next(p)) {
    path = (T) List_head(p);
    printf("** Complete qstart path, sense %p: ",path);
    Path_print(path);
  }

  if (splicingp == true) {
    for (p = qstart_antisense_paths; p != NULL; p = List_next(p)) {
      path = (T) List_head(p);
      printf("** Complete qstart path, antisense %p: ",path);
      Path_print(path);
    }
  }

  for (p = qend_sense_paths; p != NULL; p = List_next(p)) {
    path = (T) List_head(p);
    printf("** Complete qend path, sense %p: ",path);
    Path_print(path);
  }

  if (splicingp == true) {
    for (p = qend_antisense_paths; p != NULL; p = List_next(p)) {
      path = (T) List_head(p);
      printf("** Complete qend path, antisense %p: ",path);
      Path_print(path);
      printf("\n");
    }
  }
#endif

  if (qstart_sense_paths != NULL && qend_sense_paths != NULL) {
    combined_sense_paths = combine_leftright_paths(&(*found_score),qstart_sense_paths,qend_sense_paths,
						   query_compress,query_compress_fwd,query_compress_rev,
						   queryptr,querylength,plusp,genestrand,
						   /*sensedir*/SENSE_FORWARD,chrnum,chroffset,chrhigh,
						   mismatch_positions_alloc,knownsplicing,spliceendsgen,
						   intlistpool,univcoordlistpool,listpool,pathpool,
						   vectorpool,hitlistpool,method);

    Path_gc(&qstart_sense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
    Path_gc(&qend_sense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);

  } else if (qstart_sense_paths != NULL) {
    combined_sense_paths = qstart_sense_paths;

  } else if (qend_sense_paths != NULL) {
    combined_sense_paths = qend_sense_paths;
    for (p = combined_sense_paths; p != NULL; p = List_next(p)) {
      Path_reverse((Path_T) List_head(p),/*expect_fwd_p*/true);
    }

  } else {
    combined_sense_paths = (List_T) NULL;
  }


  if (qstart_antisense_paths != NULL && qend_antisense_paths != NULL) {
    combined_antisense_paths = combine_leftright_paths(&(*found_score),qstart_antisense_paths,qend_antisense_paths,
						       query_compress,query_compress_fwd,query_compress_rev,
						       queryptr,querylength,plusp,genestrand,
						       /*sensedir*/SENSE_ANTI,chrnum,chroffset,chrhigh,
						       mismatch_positions_alloc,knownsplicing,spliceendsgen,
						       intlistpool,univcoordlistpool,listpool,pathpool,
						       vectorpool,hitlistpool,method);
    Path_gc(&qstart_antisense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
    Path_gc(&qend_antisense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
    
  } else if (qstart_antisense_paths != NULL) {
    combined_antisense_paths = qstart_antisense_paths;

  } else if (qend_antisense_paths != NULL) {
    combined_antisense_paths = qend_antisense_paths;
    for (p = combined_antisense_paths; p != NULL; p = List_next(p)) {
      Path_reverse((Path_T) List_head(p),/*expect_fwd_p*/true);
    }
    
  } else {
    combined_antisense_paths = (List_T) NULL;
  }

  debug13(printf("After combining qstart and qend, combined_sense_paths: %d, combined_antisense_paths %d\n",
		 List_length(combined_sense_paths),List_length(combined_antisense_paths)));


  /* Want to treat sense and antisense equally in terms of complete
     versus unextended paths.  So we set endtrim_allowed to be 0 and
     set allow_ambig_p to be true.  We perform the same action on all
     paths found */
  
  sense_completep = false;
  for (p = combined_sense_paths; p != NULL; p = List_next(p)) {
    path = (T) List_head(p);
    /* Cannot trust ambig */
    if (Path_unextendedp(path,/*endtrim_allowed*/0,/*allow_ambig_p*/true) == false) {
      debug13(printf("Path is complete: ")); debug13(Path_print(path));
      sense_completep = true;
    }
  }

  antisense_completep = false;
  for (p = combined_antisense_paths; p != NULL; p = List_next(p)) {
    path = (T) List_head(p);
    /* Cannot trust ambig */
    if (Path_unextendedp(path,/*endtrim_allowed*/0,/*allow_ambig_p*/true) == false) {
      debug13(printf("Path is complete: ")); debug13(Path_print(path));
      antisense_completep = true;
    }
  }
  debug13(printf("sense_completep %d, antisense_completep %d\n",sense_completep,antisense_completep));

    
  if (sense_completep == false) {
    /* Put into unextended in case the complete antisense path over-reaches the other end of a paired-end read */
    *unextended_sense_paths = List_append(combined_sense_paths,*unextended_sense_paths);
  } else {
    for (p = combined_sense_paths; p != NULL; p = List_next(p)) {
      path = (T) List_head(p);
      if (transcriptome == NULL) {
	*sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) Path_expect_fwd(path)
				    hitlistpool_trace(__FILE__,__LINE__));
#if 0
      } else if (path->transcriptome_method_p == true) {
	/* Not possible */
	*sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) Path_expect_fwd(path)
				    hitlistpool_trace(__FILE__,__LINE__));
#endif
      } else if (try_repairs(&(*found_score),&(*found_transcriptp),&(*sense_paths),
			     path,query_compress_fwd,query_compress_rev,queryseq,
			     intlistpool,uintlistpool,univcoordlistpool,listpool,
			     transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
	*sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) Path_expect_fwd(path)
				    hitlistpool_trace(__FILE__,__LINE__));
      } else {
	Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
    }
  }
  Hitlistpool_free_list(&combined_sense_paths,hitlistpool
			hitlistpool_trace(__FILE__,__LINE__)); /* Allocated by Hitlist_push */

  if (antisense_completep == false) {
    /* Put into unextended in case the complete sense path over-reaches the other end of a paired-end read */
    *unextended_antisense_paths = List_append(combined_antisense_paths,*unextended_antisense_paths);
  } else {
    for (p = combined_antisense_paths; p != NULL; p = List_next(p)) {
      path = (T) List_head(p);
      if (transcriptome == NULL) {
	*antisense_paths = Hitlist_push(*antisense_paths,hitlistpool,(void *) Path_expect_fwd(path)
					hitlistpool_trace(__FILE__,__LINE__));
#if 0
      } else if (path->transcriptome_method_p(path) == true) {
	*antisense_paths = Hitlist_push(*antisense_paths,hitlistpool,(void *) Path_expect_fwd(path)
					hitlistpool_trace(__FILE__,__LINE__));
#endif
      } else if (try_repairs(&(*found_score),&(*found_transcriptp),&(*antisense_paths),
			     path,query_compress_fwd,query_compress_rev,queryseq,
			     intlistpool,uintlistpool,univcoordlistpool,listpool,
			     transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
	*antisense_paths = Hitlist_push(*antisense_paths,hitlistpool,(void *) Path_expect_fwd(path)
					hitlistpool_trace(__FILE__,__LINE__));
      } else {
	Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
      }
    }
  }
  Hitlistpool_free_list(&combined_antisense_paths,hitlistpool
			hitlistpool_trace(__FILE__,__LINE__)); /* Allocated by Hitlist_push */

#ifdef DEBUG13
  printf("Result: first_read_p %d, plusp %d\n",first_read_p,plusp);
  printf("Result: %d complete sense paths\n",List_length(*sense_paths));
  printf("Result: %d complete antisense paths\n",List_length(*antisense_paths));
  printf("Result: %d unextended sense paths\n",List_length(*unextended_sense_paths));
  printf("Result: %d unextended antisense paths\n",List_length(*unextended_antisense_paths));
#endif

#if 0  
  /* Already freed or used above */
  Path_gc(&qstart_sense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
  Path_gc(&qend_sense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
  Path_gc(&qstart_antisense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
  Path_gc(&qend_antisense_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
#endif

  return;
}


void
Path_solve_from_ends (int *found_score, bool *found_transcriptp,
		      List_T *unsolved_paths, List_T *paths,
		      Univcoord_T univdiagonal_i, int pos5_0, int pos3_0,
		      Univcoord_T univdiagonal_j, int pos5_1, int pos3_1,
		      bool plusp, int sensedir, int genestrand,
		      Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
		      Shortread_T queryseq, int querylength,
		      Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
		      Indelinfo_T indelinfo, Spliceinfo_T spliceinfo, Knownsplicing_T knownsplicing,
		      Intlistpool_T intlistpool, Uintlistpool_T uintlistpool, Univcoordlistpool_T univcoordlistpool,
		      Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool, Transcriptpool_T transcriptpool,
		      Hitlistpool_T hitlistpool, int max_insertionlen, int max_deletionlen,
		      Method_T method) {
  T path = NULL;
  
  int nmismatches_i, nmismatches_j, nmismatches_indel, nmismatches_middle,
    ref_nmismatches_i, ref_nmismatches_j, ref_nmismatches_indel, ref_nmismatches_middle;
  int nindels;
  int supporti, supportj;
  double donor_prob, acceptor_prob;

  int splice_qpos, splice_qpos_i, splice_qpos_j, indel_pos, qstart, qend;
  /* Univcoord_T segmentj_left; */
  Univcoord_T middle_univdiagonal, segmenti_left, deletionpos;
  Chrpos_T splice_distance, splice_distance_i, splice_distance_j;

  List_T j;
  Intlist_T q;
  Intlist_T r, s;
  Univcoordlist_T p;
  Junction_T junction;


  debug13(printf("Entered Path_solve_from_ends, with low_univdiagonal %u, %d..%d, and univdiagonal_j %u, %d..%d, max_insertionlen %d\n",
		 univdiagonal_i - chroffset,pos5_0,pos3_0,univdiagonal_j - chroffset,pos5_1,pos3_1,max_insertionlen));
  assert(univdiagonal_i != univdiagonal_j); /* Caller should handle this case */

  segmenti_left = univdiagonal_i - querylength;
  /* segmentj_left = univdiagonal_j - querylength; */

  qstart = pos5_0;
  qend = pos3_1;

  /* Follows attach_unknown_qstart and attach_unknown_qend */
  if (univdiagonal_i > univdiagonal_j + max_insertionlen) {
    /* Impossible */
    debug13(printf("Impossible\n"));

  } else if (univdiagonal_i > univdiagonal_j) {
    /* (A) Insertion */
    nindels = univdiagonal_i - univdiagonal_j;
    if ((indel_pos = Indel_resolve_middle_insertion(&nmismatches_i,&nmismatches_j,
						    &ref_nmismatches_i,&ref_nmismatches_j,
						    /*univdiagonal*/univdiagonal_i,/*indels*/+nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						    /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						    /*pos5*/qstart,/*pos3*/qend,querylength,
						    indelinfo,plusp,genestrand,
						    /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("(5) Insertion fails\n"));

    } else {
      supporti = indel_pos - qstart;
      supportj = qend - (indel_pos + nindels);
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
	
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	path = Path_new_from_ends(univdiagonal_i,pos5_0,pos3_0,univdiagonal_j,pos5_1,pos3_1,
				  plusp,genestrand,sensedir,querylength,
				  method,chrnum,chroffset,chrhigh,
				  intlistpool,univcoordlistpool,listpool,pathpool);
	j = path->junctions; p = path->univdiagonals; q = path->endpoints; r = path->ref_nmismatches; s = path->nmismatches;

	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_insertion(nindels,pathpool));

	/* No need to change univdiagonals */
	Intlist_head_set(q->rest,indel_pos);
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
      }
    }

  } else if (univdiagonal_i + max_deletionlen >= univdiagonal_j) {
    /* (B) Deletion (or short intron) */
    nindels = univdiagonal_j - univdiagonal_i;
    if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						   &ref_nmismatches_i,&ref_nmismatches_j,
						   /*univdiagonal*/univdiagonal_i,/*indels*/-nindels,chrhigh,
						    /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						    /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						   /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						   /*pos5*/qstart,/*pos3*/qend,querylength,
						   indelinfo,plusp,genestrand,
						   /*want_lowest_coordinate_p*/true)) <= 0) {
      debug13(printf("Deletion or short intron fails\n"));
	  
    } else {
      supporti = indel_pos - qstart;
      supportj = qend - indel_pos;
      if (supporti - 3*nmismatches_i < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supporti,nmismatches_i));
      } else if (supportj - 3*nmismatches_j < MIN_SUPPORT_INDEL) {
	debug13(printf("Not enough support for indel: supporti %d and mismatches %d\n",supportj,nmismatches_j));
      } else {
	path = Path_new_from_ends(univdiagonal_i,pos5_0,pos3_0,univdiagonal_j,pos5_1,pos3_1,
				  plusp,genestrand,sensedir,querylength,
				  method,chrnum,chroffset,chrhigh,
				  intlistpool,univcoordlistpool,listpool,pathpool);
	j = path->junctions; p = path->univdiagonals; q = path->endpoints; r = path->ref_nmismatches; s = path->nmismatches;

	assert(nindels >= 0);
	deletionpos = segmenti_left + indel_pos;

	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_deletion(nindels,deletionpos,pathpool));

	/* No need to change univdiagonals */
	Intlist_head_set(q->rest,indel_pos);
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
      }
    }

#ifdef DISALLOW_CIRCULAR_SPLICING
  } else if (circularp[chrnum] == true) {
    /* No splicing on circular chromosomes */
    debug13(printf("No splicing on circular chromosomes\n"));
#endif

  } else {
    /* (C) Splice with possible indel */
    if (sensedir == SENSE_FORWARD) {
      path = Path_new_from_ends(univdiagonal_i,pos5_0,pos3_0,univdiagonal_j,pos5_1,pos3_1,
				plusp,genestrand,sensedir,querylength,
				method,chrnum,chroffset,chrhigh,
				intlistpool,univcoordlistpool,listpool,pathpool);
      j = path->junctions; p = path->univdiagonals; q = path->endpoints; r = path->ref_nmismatches; s = path->nmismatches;

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					univdiagonal_i,univdiagonal_j,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/qstart,/*pos3*/qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/true,
					genestrand,max_insertionlen,max_deletionlen,
					/*salvagep*/false,/*check_support_p*/true)) < 0) {

	if (middle_univdiagonal != 0) {
	  j = path->junctions; p = path->univdiagonals; q = path->endpoints; r = path->ref_nmismatches; s = path->nmismatches;

	  debug13(printf("Splice_resolve (qstart, sense): found a middle exon\n"));
	  splice_distance_j = univdiagonal_j - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - univdiagonal_i;

	  Intlist_head_set(q->rest,splice_qpos_j);
	  q->rest = Intlistpool_push(q->rest,intlistpool,splice_qpos_i
				     intlistpool_trace(__FILE__,__LINE__));

	  j->rest = Listpool_push(j->rest,listpool,
				  (void *) Junction_new_splice(splice_distance_j,SENSE_FORWARD,
							       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
							       pathpool)
				  listpool_trace(__FILE__,__LINE__));

	  junction = (Junction_T) List_head(j);
	  Junction_free(&junction,pathpool);
	  List_head_set(j,(void *) Junction_new_splice(splice_distance_i,SENSE_FORWARD,
						       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
						       pathpool));

	  Intlist_head_set(s->rest,nmismatches_j);
	  Intlist_head_set(r->rest,ref_nmismatches_j);
	  s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  Intlist_head_set(s,nmismatches_i);
	  Intlist_head_set(r,ref_nmismatches_i);
	
	  p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					   univcoordlistpool_trace(__FILE__,__LINE__));

	} else {
	  /* Leave the junction as unsolved, but move to unsolved paths.  Already in qstart direction */
	  debug13(printf("Splice_resolve (qstart, sense) fails, so leaving junction as unsolved\n"));
	  debug20(printf("Moving path %p into unsolved paths\n",path));
	  *unsolved_paths = Hitlist_push(*unsolved_paths,hitlistpool,(void *) Path_expect_fwd(path)
					 hitlistpool_trace(__FILE__,__LINE__));
	  path = (T) NULL;
	}

      } else if (donor_prob < 0.9 || acceptor_prob < 0.9) {
	/* Specific to Path_solve_from_ends, which can get bad input */
	/* Leave the junction as unsolved, but move to unsolved paths.  Already in qstart direction */
	debug13(printf("Splice_resolve (qstart, sense) fails, so leaving junction as unsolved\n"));
	debug20(printf("Moving path %p into unsolved paths\n",path));
	*unsolved_paths = Hitlist_push(*unsolved_paths,hitlistpool,(void *) Path_expect_fwd(path)
				       hitlistpool_trace(__FILE__,__LINE__));
	path = (T) NULL;
	
      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = univdiagonal_j - univdiagonal_i;
	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	/* No need to change univdiagonals in p */

	Intlist_head_set(q->rest,splice_qpos);

	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
						     donor_prob,acceptor_prob,pathpool));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);

      } else if (splice_qpos < indel_pos) {
	/* Push indel (based on left) then splice.  splice is distal, indel is medial */
	middle_univdiagonal = univdiagonal_j - nindels; /* nindels = univdiagonal_j - middle_univdiagonal */
	splice_distance = middle_univdiagonal - univdiagonal_i;

	debug13(printf("Splice_resolve (qstart, sense): %d indels at %d, mismatches %d, then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,nmismatches_indel,
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(q->rest,indel_pos);
	q->rest = Intlistpool_push(q->rest,intlistpool,splice_qpos
				   intlistpool_trace(__FILE__,__LINE__));

	/* Indel first */
	if (nindels < 0) {
	  j->rest = Listpool_push(j->rest,listpool,(void *) Junction_new_insertion(-nindels,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = segmenti_left + indel_pos;
	  j->rest = Listpool_push(j->rest,listpool,(void *) Junction_new_deletion(nindels,deletionpos,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
						     donor_prob,acceptor_prob,pathpool));
	  
	/* For endpoints in ascending order, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
	  
	p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					 univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on univdiagonal_i).  indel is distal, splice is medial */
	middle_univdiagonal = univdiagonal_i + nindels; /* nindels = middle_univdiagonal - univdiagonal_i */
	splice_distance = univdiagonal_j - middle_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d, nmismatches %d\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos,nmismatches_indel));

	Intlist_head_set(q->rest,splice_qpos);
	q->rest = Intlistpool_push(q->rest,intlistpool,indel_pos
				   intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	j->rest = Listpool_push(j->rest,listpool,
				(void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
							     donor_prob,acceptor_prob,pathpool)
				listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	if (nindels < 0) {
	  List_head_set(j,(void *) Junction_new_insertion(-nindels,pathpool));
	} else {
	  deletionpos = segmenti_left + indel_pos;
	  List_head_set(j,(void *) Junction_new_deletion(nindels,deletionpos,pathpool));
	}
	  
	/* For endpoints in ascending order, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
	  
	p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					 univcoordlistpool_trace(__FILE__,__LINE__));
      }

    } else {
      /* Antisense */
      path = Path_new_from_ends(univdiagonal_i,pos5_0,pos3_0,univdiagonal_j,pos5_1,pos3_1,
				plusp,genestrand,sensedir,querylength,
				method,chrnum,chroffset,chrhigh,
				intlistpool,univcoordlistpool,listpool,pathpool);
      j = path->junctions; p = path->univdiagonals; q = path->endpoints; r = path->ref_nmismatches; s = path->nmismatches;

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					univdiagonal_i,univdiagonal_j,
					query_compress,plusp,chroffset,chrhigh,
					/*pos5*/qstart,/*pos3*/qend,querylength,
					indelinfo,spliceinfo,knownsplicing,/*sense_forward_p*/false,
					genestrand,max_insertionlen,max_deletionlen,
					/*salvagep*/false,/*check_support_p*/true)) < 0) {

	if (middle_univdiagonal != 0) {
	  debug13(printf("Splice_resolve (qstart, sense): found a middle exon\n"));
	  splice_distance_j = univdiagonal_j - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - univdiagonal_i;

	  Intlist_head_set(q->rest,splice_qpos_j);
	  q->rest = Intlistpool_push(q->rest,intlistpool,splice_qpos_i
				     intlistpool_trace(__FILE__,__LINE__));

	  j->rest = Listpool_push(j->rest,listpool,
				  (void *) Junction_new_splice(splice_distance_j,SENSE_ANTI,
							       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
							       pathpool)
				  listpool_trace(__FILE__,__LINE__));

	  junction = (Junction_T) List_head(j);
	  Junction_free(&junction,pathpool);
	  List_head_set(j,(void *) Junction_new_splice(splice_distance_i,SENSE_ANTI,
						       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
						       pathpool));

	  Intlist_head_set(s->rest,nmismatches_j);
	  Intlist_head_set(r->rest,ref_nmismatches_j);
	  s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  Intlist_head_set(s,nmismatches_i);
	  Intlist_head_set(r,ref_nmismatches_i);
	
	  p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					   univcoordlistpool_trace(__FILE__,__LINE__));

	} else {
	  /* Leave the junction as unsolved, but move to unsolved paths.  Already in qstart direction */
	  debug13(printf("Splice_resolve (qstart, sense) fails, so leaving junction as unsolved\n"));
	  debug20(printf("Moving path %p into unsolved paths\n",path));
	  *unsolved_paths = Hitlist_push(*unsolved_paths,hitlistpool,(void *) Path_expect_fwd(path)
					 hitlistpool_trace(__FILE__,__LINE__));
	  path = (T) NULL;
	}

      } else if (donor_prob < 0.9 || acceptor_prob < 0.9) {
	/* Specific to Path_solve_from_ends, which can get bad input */
	/* Leave the junction as unsolved, but move to unsolved paths.  Already in qstart direction */
	debug13(printf("Splice_resolve (qstart, sense) fails, so leaving junction as unsolved\n"));
	debug20(printf("Moving path %p into unsolved paths\n",path));
	*unsolved_paths = Hitlist_push(*unsolved_paths,hitlistpool,(void *) Path_expect_fwd(path)
				       hitlistpool_trace(__FILE__,__LINE__));
	path = (T) NULL;

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = univdiagonal_j - univdiagonal_i;
	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	/* No need to change univdiagonals in p */

	Intlist_head_set(q->rest,splice_qpos);

	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_splice(splice_distance,SENSE_ANTI,
						     donor_prob,acceptor_prob,pathpool));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);

      } else if (splice_qpos < indel_pos) {
	/* Push indel (based on left) then splice.  splice is distal, indel is medial */
	middle_univdiagonal = univdiagonal_j - nindels; /* nindels = univdiagonal_j - middle_univdiagonal */
	splice_distance = middle_univdiagonal - univdiagonal_i;

	debug13(printf("Splice_resolve (qstart, sense): %d indels at %d, mismatches %d, then splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       nindels,indel_pos,nmismatches_indel,
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	Intlist_head_set(q->rest,indel_pos);
	q->rest = Intlistpool_push(q->rest,intlistpool,splice_qpos
				   intlistpool_trace(__FILE__,__LINE__));

	/* Indel first */
	if (nindels < 0) {
	  j->rest = Listpool_push(j->rest,listpool,(void *) Junction_new_insertion(-nindels,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	} else {
	  deletionpos = segmenti_left + splice_distance + indel_pos; /* qstart; add splice_distance if indel first */
	  j->rest = Listpool_push(j->rest,listpool,(void *) Junction_new_deletion(nindels,deletionpos,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	}
	  
	/* Splice second */
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	List_head_set(j,(void *) Junction_new_splice(splice_distance,SENSE_ANTI,
						     donor_prob,acceptor_prob,pathpool));
	  
	/* For endpoints in ascending order, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
	  
	p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					 univcoordlistpool_trace(__FILE__,__LINE__));

      } else {
	/* Push splice then indel (based on univdiagonal_i).  indel is distal, splice is medial */
	middle_univdiagonal = univdiagonal_i + nindels; /* nindels = middle_univdiagonal - univdiagonal_i */
	splice_distance = univdiagonal_j - middle_univdiagonal;

	debug13(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f, then %d indels at %d, nmismatches %d\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob,
		       nindels,indel_pos,nmismatches_indel));

	Intlist_head_set(q->rest,splice_qpos);
	q->rest = Intlistpool_push(q->rest,intlistpool,indel_pos
				   intlistpool_trace(__FILE__,__LINE__));
	  
	/* Splice first */
	j->rest = Listpool_push(j->rest,listpool,
				(void *) Junction_new_splice(splice_distance,SENSE_ANTI,
							     donor_prob,acceptor_prob,pathpool)
				listpool_trace(__FILE__,__LINE__));
	  
	/* Indel second */
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
	if (nindels < 0) {
	  List_head_set(j,(void *) Junction_new_insertion(-nindels,pathpool));
	} else {
	  deletionpos = segmenti_left + indel_pos; /* qstart; do not add splice_distance if indel second */
	  List_head_set(j,(void *) Junction_new_deletion(nindels,deletionpos,pathpool));
	}
	  
	/* For endpoints in ascending order, push j first, then push i */
	Intlist_head_set(s->rest,nmismatches_j);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	s->rest = Intlistpool_push(s->rest,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	r->rest = Intlistpool_push(r->rest,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__));
	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(r,ref_nmismatches_i);
	  
	p->rest = Univcoordlistpool_push(p->rest,univcoordlistpool,middle_univdiagonal
					 univcoordlistpool_trace(__FILE__,__LINE__));
      }
    }
  }

  if (path == NULL) {
    debug13(printf("Could not be solved\n"));

  } else if (endpoints_acceptable_p(path->endpoints,path->junctions) == false) {
    debug13(printf("Endpoints were not acceptable\n"));
    Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);

#if 0
  } else if (preliminary_score_within_trims(path->nmismatches) > nmismatches_allowed) {
    /* No need to proceed */
    debug1(printf("Path_solve_from_ends: Not considering because preliminary score within trims %d > nmismatches_allowed %d\n",
		  preliminary_score_within_trims(path->nmismatches),nmismatches_allowed));
    Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
#endif

  } else if (sensedir == SENSE_FORWARD) {
    /* sense */
    /* More efficient to perform Path_eval_nmatches here, while relevant parts of genome are still in memory */
    Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);
    if (transcriptome == NULL) {
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
#if 0
    } else if (path->transcriptome_method_p == true) {
      /* Not possible */
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
#endif
    } else if (try_repairs(&(*found_score),&(*found_transcriptp),&(*paths),
			   path,query_compress_fwd,query_compress_rev,queryseq,
			   intlistpool,uintlistpool,univcoordlistpool,listpool,
			   transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
    } else {
      Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
    }

  } else {
    /* antisense */
    /* More efficient to perform Path_eval_nmatches here, while relevant parts of genome are still in memory */
    Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);
    if (transcriptome == NULL) {
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
#if 0
    } else if (path->transcriptome_method_p == true) {
      /* Not possible */
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
#endif
    } else if (try_repairs(&(*found_score),&(*found_transcriptp),&(*paths),
			   path,query_compress_fwd,query_compress_rev,queryseq,
			   intlistpool,uintlistpool,univcoordlistpool,listpool,
			   transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
      *paths = Hitlist_push(*paths,hitlistpool,(void *) path
			    hitlistpool_trace(__FILE__,__LINE__));
    } else {
      Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
    }
  }
  
  return;
}


bool
Path_solve_exact (int *found_score, bool *found_transcriptp, List_T *sense_paths, List_T *antisense_paths,
		  Univcoord_T univdiagonal, int pos5, int pos3, bool plusp, int genestrand,
		  Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
		  Shortread_T queryseq, char *queryuc_ptr, char *queryrc, int querylength,
		  Chrnum_T chrnum, Univcoord_T chroffset, Univcoord_T chrhigh,
		  Intlistpool_T intlistpool, Uintlistpool_T uintlistpool, Univcoordlistpool_T univcoordlistpool,
		  Listpool_T listpool, Pathpool_T pathpool, Vectorpool_T vectorpool,
		  Hitlistpool_T hitlistpool, Transcriptpool_T transcriptpool, Method_T method) {
  bool perfect_ends_p = true;
  T sense_path, antisense_path;
  int nmismatches, ref_nmismatches;


  /* Determine nmismatches */
  nmismatches = Genomebits_count_mismatches_substring(&ref_nmismatches,genomebits,genomebits_alt,query_compress,
						      univdiagonal,querylength,pos5,pos3,plusp,genestrand);
  /* debug13(printf("Counting mismatches from %d to %d => %d (%d ref)\n",
     pos5,pos3,nmismatches,ref_nmismatches)); */
      
#if 0
  if (nmismatches > nmismatches_allowed) {
    debug1(printf("Path_solve_exact: Not considering because nmismatches %d > nmismatches_allowed %d\n",
		  nmismatches,nmismatches_allowed));
    return true;		/* Caller is looking for cases of imperfect ends */

  } else {
#endif
    sense_path = Path_new_exact(univdiagonal,pos5,pos3,nmismatches,ref_nmismatches,
				plusp,genestrand,querylength,method,
				chrnum,chroffset,chrhigh,intlistpool,univcoordlistpool,pathpool);
    Path_eval_nmatches(&(*found_score),sense_path,query_compress_fwd,query_compress_rev);
    perfect_ends_p = Path_eval_perfect_ends_p(sense_path,query_compress_fwd,queryuc_ptr,
					      query_compress_rev,queryrc,pathpool);

    if (splicingp == false) {
      *sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) sense_path
				  hitlistpool_trace(__FILE__,__LINE__));
    } else {
      antisense_path = Path_copy(sense_path,intlistpool,univcoordlistpool,listpool,
				 pathpool,vectorpool,transcriptpool);
      antisense_path->sensedir = SENSE_ANTI;

      if (transcriptome == NULL) {
	*sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) sense_path
				    hitlistpool_trace(__FILE__,__LINE__));
	*antisense_paths = Hitlist_push(*antisense_paths,hitlistpool,(void *) antisense_path
					hitlistpool_trace(__FILE__,__LINE__));

      } else {
	if (try_repairs(&(*found_score),&(*found_transcriptp),&(*sense_paths),
			sense_path,query_compress_fwd,query_compress_rev,queryseq,
			intlistpool,uintlistpool,univcoordlistpool,listpool,
			transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
	  *sense_paths = Hitlist_push(*sense_paths,hitlistpool,(void *) sense_path
				      hitlistpool_trace(__FILE__,__LINE__));
	} else {
	  Path_free(&sense_path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
	}

	if (try_repairs(&(*found_score),&(*found_transcriptp),&(*antisense_paths),
			antisense_path,query_compress_fwd,query_compress_rev,queryseq,
			intlistpool,uintlistpool,univcoordlistpool,listpool,
			transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
	  *antisense_paths = Hitlist_push(*antisense_paths,hitlistpool,(void *) antisense_path
					  hitlistpool_trace(__FILE__,__LINE__));
	} else {
	  Path_free(&antisense_path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
	}
      }
    }

    return perfect_ends_p;
#if 0
  }
#endif
}



static List_T
remap_paths (int *found_score, bool *found_transcriptp, List_T paths,
	     Compress_T query_compress_fwd, Compress_T query_compress_rev,
	     Shortread_T queryseq, Intlistpool_T intlistpool, Uintlistpool_T uintlistpool,
	     Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
	     Transcriptpool_T transcriptpool, Vectorpool_T vectorpool,
	     Pathpool_T pathpool, Hitlistpool_T hitlistpool) {
  List_T result_paths = NULL, p;
  T path;

  for (p = paths; p != NULL; p = List_next(p)) {
    path = (T) List_head(p);
    Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);

    if (transcriptome == NULL) {
      result_paths = Hitlist_push(result_paths,hitlistpool,(void *) path
				  hitlistpool_trace(__FILE__,__LINE__));
    } else if (try_repairs(&(*found_score),&(*found_transcriptp),&result_paths,
			   path,query_compress_fwd,query_compress_rev,queryseq,
			   intlistpool,uintlistpool,univcoordlistpool,listpool,
			   transcriptpool,pathpool,vectorpool,hitlistpool) == false) {
      result_paths = Hitlist_push(result_paths,hitlistpool,(void *) path
				  hitlistpool_trace(__FILE__,__LINE__));
    } else {
      Path_free(&path,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool);
    }
  }

  Hitlistpool_free_list(&paths,hitlistpool
			hitlistpool_trace(__FILE__,__LINE__));

  return result_paths;
}


List_T
Path_extend (bool *completep, int *found_score, bool *found_transcriptp,
	     T original_path, Shortread_T queryseq, char *queryptr, int querylength,
	     int *mismatch_positions_alloc, Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
	     int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
	     Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,
	     Indelinfo_T indelinfo, Spliceinfo_T spliceinfo,
	     Knownsplicing_T knownsplicing, Knownindels_T knownindels,
	     Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
	     int genestrand, int max_insertionlen, int max_deletionlen, Chrpos_T overall_end_distance,
	     int localdb_nmismatches_allowed, bool paired_end_p, bool lowp,
	     Intlistpool_T intlistpool, Uintlistpool_T uintlistpool, Univcoordlistpool_T univcoordlistpool,
	     Listpool_T listpool, Pathpool_T pathpool, Transcriptpool_T transcriptpool,
	     Vectorpool_T vectorpool, Hitlistpool_T hitlistpool,
	     Spliceendsgen_T spliceendsgen, Pass_T pass, bool extend_qstart_p, bool extend_qend_p) {

  List_T complete_paths, unextended_paths = NULL,
    unextended_qstart_paths = NULL, complete_qstart_paths = NULL,
    complete_qend_paths = NULL, rev_paths, p;
  T path;
  bool qstart_innerp, qend_innerp;
  Chrnum_T chrnum = original_path->chrnum;
  Univcoord_T chroffset = original_path->chroffset, chrhigh = original_path->chrhigh;

  debug13(printf("Entered Path_extend, sensedir %s, with path\n",
		 original_path->sensedir == SENSE_FORWARD ? "fwd" : "anti"));
  debug13(Path_print(original_path));

  assert(original_path->transcriptome_method_p == false);
  
  if (paired_end_p == false) {
    qstart_innerp = qend_innerp = false;
  } else if (lowp) {
    qstart_innerp = false;
    qend_innerp = true;
  } else {
    qstart_innerp = true;
    qend_innerp = false;
  }

  compute_qstart_local(&unextended_qstart_paths,&complete_qstart_paths,
		       /*depth*/0,original_path,queryptr,querylength,
		       mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
		       streamspace_max_alloc,streamspace_alloc,
		       streamptr_alloc,streamsize_alloc,mergeinfo,
		       indelinfo,spliceinfo,knownsplicing,knownindels,
		       query_compress,chrnum,chroffset,chrhigh,intlistpool,
		       univcoordlistpool,listpool,pathpool,transcriptpool,
		       vectorpool,hitlistpool,spliceendsgen,
		       max_insertionlen,max_deletionlen,
		       localdb_nmismatches_allowed,overall_end_distance,original_path->plusp,genestrand,
		       original_path->sensedir,qstart_innerp,/*salvagep*/true,pass);

  if (complete_qstart_paths != NULL) {
    Path_gc(&unextended_qstart_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
    rev_paths = complete_qstart_paths;
  } else {
    rev_paths = unextended_qstart_paths;
  }
  
  for (p = rev_paths; p != NULL; p = List_next(p)) {
    path = Path_reverse((Path_T) List_head(p),/*expect_fwd_p*/false);
    compute_qend_local(&unextended_paths,&complete_qend_paths,
		       /*depth*/0,path,queryptr,querylength,
		       mismatch_positions_alloc,novel_diagonals_alloc,localdb_alloc,
		       streamspace_max_alloc,streamspace_alloc,
		       streamptr_alloc,streamsize_alloc,mergeinfo,
		       indelinfo,spliceinfo,knownsplicing,knownindels,
		       query_compress,chrnum,chroffset,chrhigh,intlistpool,
		       univcoordlistpool,listpool,pathpool,transcriptpool,
		       vectorpool,hitlistpool,spliceendsgen,
		       max_insertionlen,max_deletionlen,
		       localdb_nmismatches_allowed,overall_end_distance,original_path->plusp,genestrand,
		       original_path->sensedir,qend_innerp,/*salvagep*/true,pass);
  }
  Path_gc(&rev_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);


  if (complete_qend_paths == NULL) {
    debug11(printf("complete qend paths is NULL, so processing unextended paths\n"));
    *completep = false;
    return remap_paths(&(*found_score),&(*found_transcriptp),unextended_paths,
		       query_compress_fwd,query_compress_rev,queryseq,
		       intlistpool,uintlistpool,univcoordlistpool,
		       listpool,transcriptpool,vectorpool,pathpool,hitlistpool);

  } else {
    debug11(printf("complete qend paths is not NULL\n"));
    complete_paths = (List_T) NULL;
    for (p = complete_qend_paths; p != NULL; p = List_next(p)) {
      path = Path_reverse((Path_T) List_head(p),/*expect_fwd_p*/true);
      if (Path_unextendedp(path,/*endtrim_allowed*/8,/*allow_ambig_p*/false) == true) {
	/* Move from complete_qend to unextended (because not complete at qstart) */
	debug11(printf("Moving path to unextended\n"));
	unextended_paths = Hitlist_push(unextended_paths,hitlistpool,(void *) path
					hitlistpool_trace(__FILE__,__LINE__));
      } else {
	debug11(printf("Moving path to complete\n"));
	complete_paths = Hitlist_push(complete_paths,hitlistpool,(void *) path
				      hitlistpool_trace(__FILE__,__LINE__));
      }
    }

    if (complete_paths != NULL) {
      debug11(printf("complete paths is not NULL\n"));
      *completep = true;
      Path_gc(&unextended_paths,intlistpool,univcoordlistpool,listpool,pathpool,transcriptpool,hitlistpool);
      return remap_paths(&(*found_score),&(*found_transcriptp),complete_paths,
			 query_compress_fwd,query_compress_rev,queryseq,
			 intlistpool,uintlistpool,univcoordlistpool,
			 listpool,transcriptpool,vectorpool,pathpool,hitlistpool);
			 

    } else {
      debug11(printf("complete paths is NULL\n"));
      *completep = false;
      return remap_paths(&(*found_score),&(*found_transcriptp),unextended_paths,
			 query_compress_fwd,query_compress_rev,queryseq,
			 intlistpool,uintlistpool,univcoordlistpool,
			 listpool,transcriptpool,vectorpool,pathpool,hitlistpool);
    }
  }
}


/* Modifies path and does not create a copy */
void
Path_qstart_resolve (int *found_score, T path,
		     Univcoord_T low_univdiagonal, Univcoord_T high_univdiagonal,
		     char *queryptr, int querylength,
		     Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
		     int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
		     Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,
		     Indelinfo_T indelinfo, Spliceinfo_T spliceinfo,
		     Knownsplicing_T knownsplicing,
		     Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
		     int genestrand, int localdb_nmismatches_allowed, int max_insertionlen, int max_deletionlen,
		     Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		     Listpool_T listpool, Pathpool_T pathpool) {

  Univcoord_T new_univdiagonal, univdiagonal, middle_univdiagonal, deletionpos;
  Chrpos_T splice_distance;
  int qstart, pos3;
  int splice_qpos, splice_qpos_i, splice_qpos_j;
  int nindels, indel_pos;
  int local_nmismatches, nmismatches_i, nmismatches_middle, nmismatches_j, nmismatches_indel;
  int ref_nmismatches_i, ref_nmismatches_middle, ref_nmismatches_j, ref_nmismatches_indel;
  double donor_prob, acceptor_prob;


  debug3(printf("Entered Path_qstart_resolve, sensedir %d, univdiagonal %u..%u and path\n",
		path->sensedir,low_univdiagonal,high_univdiagonal));
  debug3(Path_print(path));

  Path_expect_fwd(path);

  univdiagonal = Univcoordlist_head(path->univdiagonals);
  if (high_univdiagonal > univdiagonal) {
    debug3(printf("Changing high_univdiagonal to be %u\n",univdiagonal));
    high_univdiagonal = univdiagonal;
  }

  if (high_univdiagonal <= low_univdiagonal) {
    /* Ends overlap, so no way to resolve */
    debug3(printf("Interval %u..%u is negative, so not resolving\n",
		  low_univdiagonal,high_univdiagonal));

#ifdef DISALLOW_CIRCULAR_SPLICING
  } else if (circularp[path->chrnum] == true) {
    /* No splicing on circular chromosomes */
    debug3(printf("No splicing on circular chromosomes\n"));
#endif

  } else {
    debug3(printf("Interval %u..%u is positive, so resolving\n",
		  low_univdiagonal,high_univdiagonal));

    qstart = Intlist_head(path->endpoints);
    pos3 = Intlist_head(Intlist_next(path->endpoints));
    if ((new_univdiagonal = Spliceends_qstart_resolve(&local_nmismatches,/*pos3*/qstart,querylength,
						      low_univdiagonal,high_univdiagonal,
						      query_compress,queryptr,path->plusp,genestrand,
						      novel_diagonals_alloc,localdb_alloc,
						      streamspace_max_alloc,streamspace_alloc,
						      streamptr_alloc,streamsize_alloc,mergeinfo,
						      localdb_nmismatches_allowed)) != 0) {
      if (new_univdiagonal == univdiagonal) {
	/* Continuation of univdiagonal */
	Intlist_head_set(path->endpoints,0);
	if (Intlist_head(path->nmismatches) >= 0) {
	  Intlist_head_incr(path->nmismatches,local_nmismatches);
	  Intlist_head_incr(path->ref_nmismatches,local_nmismatches);
	}

	path->splice5p = false;
	path->splicetype5 = NO_SPLICE;
	path->ambig_prob_5 = 0.0;


      } else if (new_univdiagonal > univdiagonal) {
	/* Insertion.  Skip */

      } else if (new_univdiagonal + max_deletionlen >= univdiagonal) {
	/* Deletion (or short intron) */
	nindels = univdiagonal - new_univdiagonal;
	if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						       &ref_nmismatches_i,&ref_nmismatches_j,
						       /*univdiagonal*/new_univdiagonal,/*indels*/-nindels,
						       Path_chrhigh(path),
						       /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						       /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						       /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						       /*pos5*/0,pos3,querylength,
						       indelinfo,path->plusp,genestrand,
						       /*want_lowest_coordinate_p*/true)) <= 0) {
	  debug3(printf("Deletion or short intron fails\n"));

	} else {
	  Intlist_head_set(path->endpoints,indel_pos);
	  path->endpoints = Intlistpool_push(path->endpoints,intlistpool,0
					     intlistpool_trace(__FILE__,__LINE__));
	
	  deletionpos = new_univdiagonal + indel_pos;
	  path->junctions = Listpool_push(path->junctions,listpool,
					  (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					  listpool_trace(__FILE__,__LINE__));

	  /* For qstart, push j first, then push i */
	  Intlist_head_set(path->nmismatches,nmismatches_j);
	  Intlist_head_set(path->ref_nmismatches,ref_nmismatches_j);
	  path->nmismatches = Intlistpool_push(path->nmismatches,intlistpool,nmismatches_i
					       intlistpool_trace(__FILE__,__LINE__));
	  path->ref_nmismatches = Intlistpool_push(path->ref_nmismatches,intlistpool,ref_nmismatches_i
						   intlistpool_trace(__FILE__,__LINE__));
      
	  path->univdiagonals = Univcoordlistpool_push(path->univdiagonals,univcoordlistpool,new_univdiagonal
						       univcoordlistpool_trace(__FILE__,__LINE__));

	  path->splice5p = false;
	  path->splicetype5 = NO_SPLICE;
	  path->ambig_prob_5 = 0.0;
	}
      
      } else if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					       &nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					       &ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					       &ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					       /*univdiagonal_i*/new_univdiagonal,/*univdiagonal_j*/univdiagonal,
					       query_compress,path->plusp,Path_chroffset(path),Path_chrhigh(path),
					       /*pos5*/0,pos3,querylength,
					       indelinfo,spliceinfo,knownsplicing,
					       /*sense_forward_p*/(path->sensedir == SENSE_FORWARD) ? true : false,
					       genestrand,max_insertionlen,max_deletionlen,
					       /*salvagep*/false,/*check_support_p*/false)) > 0
		 && nindels == 0 && donor_prob > 0.9 && acceptor_prob > 0.9) {

	Intlist_head_set(path->endpoints,splice_qpos);
	path->endpoints = Intlistpool_push(path->endpoints,intlistpool,0
					   intlistpool_trace(__FILE__,__LINE__));
	
	splice_distance = univdiagonal - new_univdiagonal;
	path->junctions = Listpool_push(path->junctions,listpool,
					(void *) Junction_new_splice(splice_distance,path->sensedir,
								     donor_prob,acceptor_prob,pathpool)
					listpool_trace(__FILE__,__LINE__));
	
	/* For qstart, push j first, then push i */
	Intlist_head_set(path->nmismatches,nmismatches_j);
	Intlist_head_set(path->ref_nmismatches,ref_nmismatches_j);
	path->nmismatches = Intlistpool_push(path->nmismatches,intlistpool,nmismatches_i
					     intlistpool_trace(__FILE__,__LINE__));
	path->ref_nmismatches = Intlistpool_push(path->ref_nmismatches,intlistpool,ref_nmismatches_i
						 intlistpool_trace(__FILE__,__LINE__));
      
	path->univdiagonals = Univcoordlistpool_push(path->univdiagonals,univcoordlistpool,new_univdiagonal
						     univcoordlistpool_trace(__FILE__,__LINE__));

	path->splice5p = false;
	path->splicetype5 = NO_SPLICE;
	path->ambig_prob_5 = 0.0;
      }

      debug3(printf("Result of Path_qstart_resolve: ")); debug3(Path_print(path));
      Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);
    }
  }

  return;
}


/* Modifies path and does not create a copy */
void
Path_qend_resolve (int *found_score, T path,
		   Univcoord_T low_univdiagonal, Univcoord_T high_univdiagonal,
		   char *queryptr, int querylength,
		   Univcoord_T *novel_diagonals_alloc, unsigned short *localdb_alloc,
		   int streamspace_max_alloc, Univcoord_T *streamspace_alloc,
		   Univcoord_T **streamptr_alloc, int *streamsize_alloc, Mergeinfo_T mergeinfo,
		   Indelinfo_T indelinfo, Spliceinfo_T spliceinfo,
		   Knownsplicing_T knownsplicing,
		   Compress_T query_compress, Compress_T query_compress_fwd, Compress_T query_compress_rev,
		   int genestrand, int localdb_nmismatches_allowed, int max_insertionlen, int max_deletionlen,
		   Intlistpool_T intlistpool, Univcoordlistpool_T univcoordlistpool,
		   Listpool_T listpool, Pathpool_T pathpool) {

  Univcoord_T new_univdiagonal, univdiagonal, middle_univdiagonal, deletionpos;
  Chrpos_T splice_distance;
  int qend, pos5;
  int splice_qpos, splice_qpos_i, splice_qpos_j;
  int nindels, indel_pos;
  int local_nmismatches, nmismatches_i, nmismatches_middle, nmismatches_j, nmismatches_indel;
  int ref_nmismatches_i, ref_nmismatches_middle, ref_nmismatches_j, ref_nmismatches_indel;
  double donor_prob, acceptor_prob;


  debug3(printf("Entered Path_qend_resolve, sensedir %d, univdiagonal %u..%u and path\n",
		path->sensedir,low_univdiagonal,high_univdiagonal));
  debug3(Path_print(path));

  Path_expect_fwd(path);

  univdiagonal = Univcoordlist_last_value(path->univdiagonals);
  if (low_univdiagonal < univdiagonal) {
    debug3(printf("Changing low_univdiagonal to be %u\n",univdiagonal));
    low_univdiagonal = univdiagonal;
  }

  if (high_univdiagonal <= low_univdiagonal) {
    /* Ends overlap, so no way to resolve */
    debug3(printf("Interval %u..%u is negative, so not resolving\n",
		  low_univdiagonal,high_univdiagonal));

#ifdef DISALLOW_CIRCULAR_SPLICING
  } else if (circularp[path->chrnum] == true) {
    /* No splicing on circular chromosomes */
    debug3(printf("No splicing on circular chromosomes\n"));
#endif

  } else {
    debug3(printf("Interval %u..%u is positive, so resolving\n",
		  low_univdiagonal,high_univdiagonal));

    qend = Intlist_last_value(path->endpoints);
    pos5 = Intlist_penultimate_value(path->endpoints);
    if (path->junctions != NULL) {
      pos5 += Junction_ninserts((Junction_T) List_last_value(path->junctions,NULL));
    }
    if ((new_univdiagonal = Spliceends_qend_resolve(&local_nmismatches,/*pos5*/qend,querylength,
						    low_univdiagonal,high_univdiagonal,
						    query_compress,queryptr,path->plusp,genestrand,
						    novel_diagonals_alloc,localdb_alloc,
						    streamspace_max_alloc,streamspace_alloc,
						    streamptr_alloc,streamsize_alloc,mergeinfo,
						    localdb_nmismatches_allowed)) != 0) {
      if (new_univdiagonal == univdiagonal) {
	/* Continuation of univdiagonal */
	Path_reverse(path,/*expect_fwd_p*/false);
	Intlist_head_set(path->endpoints,querylength);
	if (Intlist_head(path->nmismatches) >= 0) {
	  Intlist_head_incr(path->nmismatches,local_nmismatches);
	  Intlist_head_incr(path->ref_nmismatches,local_nmismatches);
	}
	Path_reverse(path,/*expect_fwd_p*/true);

	path->splice3p = false;
	path->splicetype3 = NO_SPLICE;
	path->ambig_prob_3 = 0.0;

      } else if (univdiagonal > new_univdiagonal) {
	/* Insertion.  Skip */

      } else if (univdiagonal + max_deletionlen >= new_univdiagonal) {
	/* Deletion (or short intron) */
	nindels = new_univdiagonal - univdiagonal;
	if ((indel_pos = Indel_resolve_middle_deletion(&nmismatches_i,&nmismatches_j,
						       &ref_nmismatches_i,&ref_nmismatches_j,
						       /*univdiagonal_i*/univdiagonal,/*indels*/-nindels,
						       Path_chrhigh(path),
						       /*mismatch_positions_left*/NULL,/*nmismatches_left*/0,
						       /*mismatch_positions_right*/NULL,/*nmismatches_right*/0,
						       /*ome*/genomebits,/*ome_alt*/genomebits_alt,query_compress,
						       pos5,/*pos3*/querylength,querylength,
						       indelinfo,path->plusp,genestrand,
						       /*want_lowest_coordinate_p*/true)) <= 0) {
	  debug3(printf("Deletion or short intron fails\n"));

	} else {
	  Path_reverse(path,/*expect_fwd_p*/false);
	  Intlist_head_set(path->endpoints,indel_pos);
	  path->endpoints = Intlistpool_push(path->endpoints,intlistpool,querylength
					     intlistpool_trace(__FILE__,__LINE__));
	
	  deletionpos = univdiagonal + indel_pos;
	  path->junctions = Listpool_push(path->junctions,listpool,
					  (void *) Junction_new_deletion(nindels,deletionpos,pathpool)
					  listpool_trace(__FILE__,__LINE__));

	  /* For qend, push i first, then push j */
	  Intlist_head_set(path->nmismatches,nmismatches_i);
	  Intlist_head_set(path->ref_nmismatches,ref_nmismatches_i);
	  path->nmismatches = Intlistpool_push(path->nmismatches,intlistpool,nmismatches_j
					       intlistpool_trace(__FILE__,__LINE__));
	  path->ref_nmismatches = Intlistpool_push(path->ref_nmismatches,intlistpool,ref_nmismatches_j
						   intlistpool_trace(__FILE__,__LINE__));
	
	  path->univdiagonals = Univcoordlistpool_push(path->univdiagonals,univcoordlistpool,new_univdiagonal
						       univcoordlistpool_trace(__FILE__,__LINE__));

	  Path_reverse(path,/*expect_fwd_p*/true);

	  path->splice3p = false;
	  path->splicetype3 = NO_SPLICE;
	  path->ambig_prob_3 = 0.0;
	}
      
      } else if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					       &nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					       &ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					       &ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					       /*univdiagonal_i*/univdiagonal,/*univdiagonal_j*/new_univdiagonal,
					       query_compress,path->plusp,Path_chroffset(path),Path_chrhigh(path),
					       pos5,/*pos3*/querylength,querylength,
					       indelinfo,spliceinfo,knownsplicing,
					       /*sense_forward_p*/(path->sensedir == SENSE_FORWARD) ? true : false,
					       genestrand,max_insertionlen,max_deletionlen,
					       /*salvagep*/false,/*check_support_p*/false)) > 0
		 && nindels == 0 && donor_prob > 0.9 && acceptor_prob > 0.9) {

	Path_reverse(path,/*expect_fwd_p*/false);
	Intlist_head_set(path->endpoints,splice_qpos);
	path->endpoints = Intlistpool_push(path->endpoints,intlistpool,querylength
					   intlistpool_trace(__FILE__,__LINE__));
	
	splice_distance = new_univdiagonal - univdiagonal;
	path->junctions = Listpool_push(path->junctions,listpool,
					(void *) Junction_new_splice(splice_distance,path->sensedir,
								     donor_prob,acceptor_prob,pathpool)
					listpool_trace(__FILE__,__LINE__));

	/* For qend, push i first, then push j */
	Intlist_head_set(path->nmismatches,nmismatches_i);
	Intlist_head_set(path->ref_nmismatches,ref_nmismatches_i);
	path->nmismatches = Intlistpool_push(path->nmismatches,intlistpool,nmismatches_j
					     intlistpool_trace(__FILE__,__LINE__));
	path->ref_nmismatches = Intlistpool_push(path->ref_nmismatches,intlistpool,ref_nmismatches_j
						 intlistpool_trace(__FILE__,__LINE__));
	
	path->univdiagonals = Univcoordlistpool_push(path->univdiagonals,univcoordlistpool,new_univdiagonal
						     univcoordlistpool_trace(__FILE__,__LINE__));
	Path_reverse(path,/*expect_fwd_p*/true);
    
	path->splice3p = false;
	path->splicetype3 = NO_SPLICE;
	path->ambig_prob_3 = 0.0;
      }

      debug3(printf("Result of Path_qend_resolve: ")); debug3(Path_print(path));
      Path_eval_nmatches(&(*found_score),path,query_compress_fwd,query_compress_rev);
    }
  }

  return;
}


/* Solves unsolved junctions */
T
Path_solve_junctions (int *found_score, T this, int sensedir, int genestrand,
		      int max_insertionlen, int max_deletionlen, Compress_T query_compress,
		      Compress_T query_compress_fwd, Compress_T query_compress_rev,
		      Shortread_T queryseq, int querylength,
		      Indelinfo_T indelinfo, Spliceinfo_T spliceinfo, Knownsplicing_T knownsplicing,
		      Uintlistpool_T uintlistpool, Intlistpool_T intlistpool,
		      Univcoordlistpool_T univcoordlistpool, Listpool_T listpool,
		      Pathpool_T pathpool, Transcriptpool_T transcriptpool) {
  
  int nmismatches_i, nmismatches_j, nmismatches_middle, nmismatches_indel,
    ref_nmismatches_i, ref_nmismatches_j, ref_nmismatches_middle, ref_nmismatches_indel;
  int nindels;
  double donor_prob, acceptor_prob;

  int splice_qpos, splice_qpos_i, splice_qpos_j, indel_pos, prev_ninserts, qstart, qend;
  Univcoord_T univdiagonal_i, univdiagonal_j, univdiagonal_k, middle_univdiagonal,
    segmenti_left, segmentj_left, deletionpos;
  Chrpos_T splice_distance, splice_distance_i, splice_distance_j;

  Junction_T junction;
  List_T j, jnext;	/* junctions */
  Intlist_T q, qmid, qnext; /* endpoints */
  Intlist_T r, s, rnext, snext; /* ref_nmismatches, nmismatches */
  Univcoordlist_T p, pnext;	/* univdiagonals */

#if 0
  /* If we need to make a copy */
  List_T junctions;
  Intlist_T endpoints;
  Intlist_T nmismatches, ref_nmismatches;
  Univcoordlist_T univdiagonals;
#endif

  bool all_solved_p = true;
  bool sense_forward_p = (this->sensedir == SENSE_FORWARD) ? true : false;

  List_T invalid_transcripts, t;
  Transcript_T transcript;
  bool validp;


  debug14(printf("Entered Path_solve_junctions with path\n"));
  debug14(Path_print(this));

  prev_ninserts = 0;
  j = this->junctions;
  p = this->univdiagonals;
  q = this->endpoints;
  r = this->ref_nmismatches;
  s = this->nmismatches;

  while (j != NULL) {
#ifdef DEBUG14
    printf("Endpoints: %s\n",Intlist_to_string(q));
    printf("Univdiagonals: %s\n",Univcoordlist_to_string(p));
    printf("Mismatches: %s\n",Intlist_to_string(s));
    printf("Junctions: ");
    Junction_print_list(j);
    printf("\n");
#endif

    assert(Univcoordlist_length(/*univdiagonals*/p) == Intlist_length(/*endpoints*/q) - 1);
    assert(Intlist_length(/*nmismatches*/s) == Intlist_length(/*endpoints*/q) - 1);
    assert(Intlist_length(/*ref_nmismatches*/r) == Intlist_length(/*endpoints*/q) - 1);
    assert(List_length(/*junctions*/j) == Intlist_length(/*endpoints*/q) - 2);

    junction = (Junction_T) List_head(j);
    debug14(Junction_print(junction));

    if (
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	Junction_type(junction) != UNSOLVED_JUNCTION
#else
	junction != JUNCTION_UNSOLVED
#endif
	) {

      prev_ninserts = Junction_ninserts(junction);
      j = List_next(j);
      p = Univcoordlist_next(p);
      q = Intlist_next(q);
      r = Intlist_next(r);
      s = Intlist_next(s);

    } else {
      debug14(printf("Solving unsolved junction\n"));

      univdiagonal_i = Univcoordlist_head(p);
      univdiagonal_j = Univcoordlist_head(Univcoordlist_next(p));
      segmenti_left = univdiagonal_i - querylength;
      segmentj_left = univdiagonal_j - querylength;

      qstart = Intlist_head(q) + prev_ninserts;	/* The endpoint before the junction */
      qend = Intlist_head(Intlist_next(Intlist_next(q))); /* The endpoint after the junction */

      if ((splice_qpos = Splice_resolve(&middle_univdiagonal,&splice_qpos_i,&splice_qpos_j,&nindels,&indel_pos,
					&nmismatches_i,&nmismatches_middle,&nmismatches_j,&nmismatches_indel,
					&ref_nmismatches_i,&ref_nmismatches_middle,&ref_nmismatches_j,
					&ref_nmismatches_indel,&donor_prob,&acceptor_prob,
					univdiagonal_i,univdiagonal_j,
					query_compress,this->plusp,this->chroffset,this->chrhigh,
					/*pos5*/qstart,/*pos3*/qend,querylength,
					indelinfo,spliceinfo,knownsplicing,sense_forward_p,
					genestrand,max_insertionlen,max_deletionlen,
					/*salvagep*/true,/*check_support_p*/false)) < 0) {

	if (middle_univdiagonal != 0) {
	  debug14(printf("Splice_resolve (qstart, sense): middle univdiagonal %u from %d to %d\n",
			 middle_univdiagonal,splice_qpos_i,splice_qpos_j));

	  splice_distance_j = univdiagonal_j - middle_univdiagonal;
	  splice_distance_i = middle_univdiagonal - univdiagonal_i;
	  
	  jnext = List_next(j);
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	  junction = (Junction_T) List_head(j);
	  Junction_free(&junction,pathpool);
#endif
	  List_head_set(j,(void *) Junction_new_splice(splice_distance_i,sensedir,
						       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
						       pathpool)
			listpool_trace(__FILE__,__LINE__));
	  j->rest = Listpool_push(jnext,listpool,
				  (void *) Junction_new_splice(splice_distance_j,sensedir,
							       /*donor_prob*/1.0,/*acceptor_prob*/1.0,
							       pathpool)
				  listpool_trace(__FILE__,__LINE__));
	  prev_ninserts = 0;
	  j = jnext;
	  
	  pnext = Univcoordlist_next(p);
	  p->rest = Univcoordlistpool_push(pnext,univcoordlistpool,middle_univdiagonal
					   univcoordlistpool_trace(__FILE__,__LINE__));
	  p = pnext;
	  
	  /* This is the correct order for splice_qpos_j and splice_qpos_i */
	  qnext = Intlist_next(q);
	  Intlist_head_set(q->rest,splice_qpos_j);
	  q->rest = Intlistpool_push(qnext,intlistpool,splice_qpos_i
				     intlistpool_trace(__FILE__,__LINE__));
	  q = qnext;
	  
	  snext = Intlist_next(s);
	  Intlist_head_set(s,nmismatches_i);
	  s->rest = Intlistpool_push(snext,intlistpool,nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  Intlist_head_set(snext,nmismatches_j);
	  s = snext;

	  rnext = Intlist_next(r);
	  Intlist_head_set(r,ref_nmismatches_i);
	  r->rest = Intlistpool_push(rnext,intlistpool,ref_nmismatches_middle
				     intlistpool_trace(__FILE__,__LINE__));
	  Intlist_head_set(rnext,ref_nmismatches_j);
	  r = rnext;

	} else {
	  all_solved_p = false;

	  /* prev_ninserts = 0; -- Doesn't matter */
	  j = List_next(j);
	  p = Univcoordlist_next(p);
	  q = Intlist_next(q);
	  r = Intlist_next(r);
	  s = Intlist_next(s);
	}

      } else if (nindels == 0) {
	/* Splice only */
	splice_distance = univdiagonal_j - univdiagonal_i;
	debug14(printf("Splice_resolve (qstart, sense): splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	/* No need to change univdiagonals */
	p = Univcoordlist_next(p);

	Intlist_head_set(q->rest,splice_qpos);
	q = Intlist_next(q);

#ifdef ALLOCATE_UNSOLVED_JUNCTION
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
#endif
	List_head_set(j,(void *) Junction_new_splice(splice_distance,SENSE_FORWARD,
						     donor_prob,acceptor_prob,pathpool));
	prev_ninserts = 0;
	j = List_next(j);

	Intlist_head_set(s,nmismatches_i);
	Intlist_head_set(s->rest,nmismatches_j);
	s = Intlist_next(s);

	Intlist_head_set(r,ref_nmismatches_i);
	Intlist_head_set(r->rest,ref_nmismatches_j);
	r = Intlist_next(r);

      } else if (indel_pos < splice_qpos) {
	debug14(printf("Splice_resolve (qstart, sense) with indel: splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	debug14(printf("Before fill:\n"));
	debug14(Path_print(this));
	debug14(printf("\n"));
	
	/* Indel on segmenti: revise indel (based on segmenti) then splice */
	debug14(printf("Indel on segmenti: indel_pos %d, splice_qpos %d\n",indel_pos,splice_qpos));
	univdiagonal_k = univdiagonal_i + nindels; /* nindels = univdiagonal_k - univdiagonal_i */
	splice_distance = univdiagonal_j - univdiagonal_k;
	
	jnext = List_next(j);
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
#endif
	if (nindels < 0) {
	  List_head_set(j,(void *) Junction_new_insertion(-nindels,pathpool));
	} else {
	  deletionpos = segmenti_left + indel_pos;
	  List_head_set(j,(void *) Junction_new_deletion(nindels,deletionpos,pathpool));
	}

	j->rest = Listpool_push(jnext,listpool,
				(void *) Junction_new_splice(splice_distance,sensedir,
							     donor_prob,acceptor_prob,pathpool)
				listpool_trace(__FILE__,__LINE__));
	prev_ninserts = 0;
	j = jnext;
	  
	pnext = Univcoordlist_next(p);
	p->rest = Univcoordlistpool_push(pnext,univcoordlistpool,univdiagonal_k
					 univcoordlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	p = pnext;
	
	qmid = Intlist_next(q);
	qnext = Intlist_next(qmid);
	Intlist_head_set(qmid,indel_pos);
	q = qmid->rest = Intlistpool_push(qnext,intlistpool,splice_qpos
					  intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	
	snext = Intlist_next(s);
	Intlist_head_set(s,nmismatches_i);
	s->rest = Intlistpool_push(snext,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	Intlist_head_set(snext,nmismatches_j);
	s = snext;

	rnext = Intlist_next(r);
	Intlist_head_set(r,ref_nmismatches_i);
	r->rest = Intlistpool_push(rnext,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	Intlist_head_set(rnext,ref_nmismatches_j);
	r = rnext;
	
	debug14(printf("After fill:\n"));
	debug14(Path_print(this));
	debug14(printf("\n"));
	  
      } else {
	debug14(printf("Splice_resolve (qstart, sense) with indel: splice_qpos in range %d..%d is %d with distance %u, mismatches %d+%d, and probs %f and %f\n",
		       qstart,qend,splice_qpos,splice_distance,nmismatches_i,nmismatches_j,donor_prob,acceptor_prob));

	debug14(printf("Before fill:\n"));
	debug14(Path_print(this));
	debug14(printf("\n"));

	/* Indel on segmentj: revise splice then indel (based on segmentj) */
	debug14(printf("Indel on segmentj: splice_qpos %d, indel_pos %d\n",splice_qpos,indel_pos));
	univdiagonal_k = univdiagonal_j - nindels; /* nindels = univdiagonal_j - univdiagonal_k */
	splice_distance = univdiagonal_k - univdiagonal_i;
	
	jnext = List_next(j);
#ifdef ALLOCATE_UNSOLVED_JUNCTION
	junction = (Junction_T) List_head(j);
	Junction_free(&junction,pathpool);
#endif
	List_head_set(j,(void *) Junction_new_splice(splice_distance,sensedir,donor_prob,acceptor_prob,pathpool));

	if (nindels < 0) {
	  j->rest = Listpool_push(jnext,listpool,(void *) Junction_new_insertion(-nindels,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	  prev_ninserts = -nindels;
	} else {
	  deletionpos = segmentj_left + indel_pos;
	  j->rest = Listpool_push(jnext,listpool,(void *) Junction_new_deletion(nindels,deletionpos,pathpool)
				  listpool_trace(__FILE__,__LINE__));
	  prev_ninserts = 0;
	}
	j = jnext;
	  
	pnext = Univcoordlist_next(p);
	p->rest = Univcoordlistpool_push(pnext,univcoordlistpool,univdiagonal_k
					 univcoordlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	p = pnext;
	  
	qmid = Intlist_next(q);
	qnext = Intlist_next(qmid);
	Intlist_head_set(qmid,splice_qpos);
	q = qmid->rest = Intlistpool_push(qnext,intlistpool,indel_pos
					  intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	
	snext = Intlist_next(s);
	Intlist_head_set(s,nmismatches_i);
	s->rest = Intlistpool_push(snext,intlistpool,nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	Intlist_head_set(snext,nmismatches_j);
	s = snext;

	rnext = Intlist_next(r);
	Intlist_head_set(r,ref_nmismatches_i);
	r->rest = Intlistpool_push(rnext,intlistpool,ref_nmismatches_indel
				   intlistpool_trace(__FILE__,__LINE__)); /* Insert elt and advance */
	Intlist_head_set(rnext,ref_nmismatches_j);
	r = rnext;
	
	debug14(printf("After fill:\n"));
	debug14(Path_print(this));
	debug14(printf("\n"));
      }
    }
  }

#ifdef DEBUG14
  printf("Endpoints: %s\n",Intlist_to_string(q));
  printf("Univdiagonals: %s\n",Univcoordlist_to_string(p));
  printf("Mismatches: %s\n",Intlist_to_string(s));
  printf("Junctions: ");
  Junction_print_list(j);
  printf("\n");
#endif

  assert(Univcoordlist_length(/*univdiagonals*/p) == Intlist_length(/*endpoints*/q) - 1);
  assert(Intlist_length(/*nmismatches*/s) == Intlist_length(/*endpoints*/q) - 1);
  assert(Intlist_length(/*ref_nmismatches*/r) == Intlist_length(/*endpoints*/q) - 1);
  assert(List_length(/*junctions*/j) == Intlist_length(/*endpoints*/q) - 2);


#if 0
  if (all_solved_p == false) {
    debug14(printf("Not all junctions were solved\n"));
  } else {
    /* Need to make copies of endpoints, junctions, univdiagonals, nmismatches, and ref_nmismatches */
    endpoints = Intlistpool_copy(this->endpoints,intlistpool);
    junctions = Listpool_copy(this->junctions,listpool);
  
    if (endpoints_acceptable_p(endpoints,junctions) == false) {
      debug14(printf("Endpoints were not acceptable\n"));
    } else {
      nmismatches = Intlistpool_copy(this->nmismatches,intlistpool);
      ref_nmismatches = Intlistpool_copy(this->ref_nmismatches,intlistpool);
      univdiagonals = Univcoordlistpool_copy(this->univdiagonals,univcoordlistpool);
  
#ifdef DEBUG14
      printf("\nCombined ");
      Path_print(this);
#endif
    }
  }
#endif
	
  if (all_solved_p == false) {
    debug14(printf("Not all junctions were solved\n"));
    return (T) NULL;

  } else {
    assert(List_length(this->invalid_transcripts) == 1);

    invalid_transcripts = this->invalid_transcripts;
    this->invalid_transcripts = (List_T) NULL;

    validp = false;
    for (t = invalid_transcripts; t != NULL; t = List_next(t)) {
      transcript = (Transcript_T) List_head(t);
      if (Transcript_remap_invalid(transcript,this,transcriptome,queryseq,
				   uintlistpool,listpool,transcriptpool) == true) {
	validp = true;
      }
    }
    if (validp == true) {
      this->transcriptome_method_p = true;
    } else {
      this->transcriptome_method_p = false;
    }
    Transcript_list_gc(&invalid_transcripts,listpool,transcriptpool);


    debug14(printf("After Path_solve_junctions:\n"));
    debug14(Path_print(this));
    debug14(printf("\n"));

    Path_eval_nmatches(&(*found_score),this,query_compress_fwd,query_compress_rev);

    debug14(printf("Exiting Path_solve_junctions with path\n"));
    debug14(Path_print(this));

    return this;
  }
}


void
Path_solve_setup (bool *circularp_in, Transcriptome_T transcriptome_in,
		  Genomebits_T genomebits_in, Genomebits_T genomebits_alt_in, Univcoord_T genomelength_in,
		  Localdb_T localdb_in, int min_intronlength_in,
		  bool novelsplicingp_in, bool knownsplicingp_in) {

  circularp = circularp_in;

  transcriptome = transcriptome_in;
  genomebits = genomebits_in;
  genomebits_alt = genomebits_alt_in;
  genomelength = genomelength_in;

  localdb = localdb_in;

  min_intronlength = min_intronlength_in;

  novelsplicingp = novelsplicingp_in;
  if (novelsplicingp_in == true || knownsplicingp_in == true) {
    splicingp = true;
  } else {
    splicingp = false;
  }

  return;
}


