anchor.diff:  	 * @param c the comparator used to order the range, and to search
   	 * @return the int k,  0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
   	 */
  -	proc/gallopRight(key, base, len, hint)
  -		//ASSERT(len > 0 && hint >= 0 && hint < len)
  -
  -		var/offset = 1
  -		var/lastOffset = 0
  -		if(call(cmp)(key, fetchElement(L,base+hint)) < 0)	//key <= L[base+hint]
  -			var/maxOffset = hint + 1	//therefore we want to insert somewhere in the range [base,base+hint] = [base+,base+(hint+1))
  -			while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint-offset)) < 0)	//we are iterating backwards
  -				lastOffset = offset
  -				offset = (offset << 1) + 1	//1 3 7 15
  -
  -			if(offset > maxOffset)
  -				offset = maxOffset
  -
  -			var/temp = lastOffset
  -			lastOffset = hint - offset
  -			offset = hint - temp
  -
  -		else	//key > L[base+hint]
  -			var/maxOffset = len - hint	//therefore we want to insert somewhere in the range (base+hint,base+len) = [base+hint+1, base+hint+(len-hint))
  -			while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint+offset)) >= 0)
  -				lastOffset = offset
  -				offset = (offset << 1) + 1
  -
  -			if(offset > maxOffset)
  -				offset = maxOffset
  -
  -			lastOffset += hint
  -			offset += hint
  -
  -		//ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len)
  -
  -		++lastOffset
  -		while(lastOffset < offset)
  -			var/m = lastOffset + ((offset - lastOffset) >> 1)
  -
  -			if(call(cmp)(key, fetchElement(L,base+m)) < 0)	//key <= L[base+m]
  -				offset = m
  -			else							//key > L[base+m]
  -				lastOffset = m + 1
  -
  -		//ASSERT(lastOffset == offset)
  -
  -		return offset
  +/datum/sortInstance/proc/gallopRight(key, base, len, hint)
  +	//ASSERT(len > 0 && hint >= 0 && hint < len)
  +
  +	var/offset = 1
  +	var/lastOffset = 0
  +	if(call(cmp)(key, fetchElement(L,base+hint)) < 0)	//key <= L[base+hint]
  +		var/maxOffset = hint + 1	//therefore we want to insert somewhere in the range [base,base+hint] = [base+,base+(hint+1))
  +		while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint-offset)) < 0)	//we are iterating backwards
  +			lastOffset = offset
  +			offset = (offset << 1) + 1	//1 3 7 15
  +
  +		if(offset > maxOffset)
  +			offset = maxOffset
  +
  +		var/temp = lastOffset
  +		lastOffset = hint - offset
  +		offset = hint - temp
  +
  +	else	//key > L[base+hint]
  +		var/maxOffset = len - hint	//therefore we want to insert somewhere in the range (base+hint,base+len) = [base+hint+1, base+hint+(len-hint))
  +		while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint+offset)) >= 0)
  +			lastOffset = offset
  +			offset = (offset << 1) + 1
  +
  +		if(offset > maxOffset)
  +			offset = maxOffset
  +
  +		lastOffset += hint
  +		offset += hint
  +
  +	//ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len)
  +
  +	++lastOffset
  +	while(lastOffset < offset)
  +		var/m = lastOffset + ((offset - lastOffset) >> 1)
  +
  +		if(call(cmp)(key, fetchElement(L,base+m)) < 0)	//key <= L[base+m]
  +			offset = m
  +		else							//key > L[base+m]
  +			lastOffset = m + 1
  +
  +	//ASSERT(lastOffset == offset)
  +
  +	return offset
   
   
   	//Merges two adjacent runs in-place in a stable fashion.
   	//For performance this method should only be called when len1 <= len2!
  -	proc/mergeLo(base1, len1, base2, len2)
  -		//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
  -
  -		var/cursor1 = base1
  -		var/cursor2 = base2
  -
  -		//degenerate cases
  -		if(len2 == 1)
  -			moveElement(L, cursor2, cursor1)
  -			return
  -
  -		if(len1 == 1)
  -			moveElement(L, cursor1, cursor2+len2)
  -			return
  -
  -
  -		//Move first element of second run
  -		moveElement(L, cursor2++, cursor1++)
  -		--len2
  -
  -		outer:
  -			while(1)
  -				var/count1 = 0	//# of times in a row that first run won
  -				var/count2 = 0	//	"	"	"	"	"	"  second run won
  -
  -				//do the straightfoward thin until one run starts winning consistently
  -
  -				do
  -					//ASSERT(len1 > 1 && len2 > 0)
  -					if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
  -						moveElement(L, cursor2++, cursor1++)
  -						--len2
  -
  -						++count2
  -						count1 = 0
  -
  -						if(len2 == 0)
  -							break outer
  -					else
  -						++cursor1
  -
  -						++count1
  -						count2 = 0
  -
  -						if(--len1 == 1)
  -							break outer
  -
  -				while((count1 | count2) < minGallop)
  -
  -
  -				//one run is winning consistently so galloping may provide huge benifits
  -				//so try galloping, until such time as the run is no longer consistently winning
  -				do
  -					//ASSERT(len1 > 1 && len2 > 0)
  -
  -					count1 = gallopRight(fetchElement(L,cursor2), cursor1, len1, 0)
  -					if(count1)
  -						cursor1 += count1
  -						len1 -= count1
  -
  -						if(len1 <= 1)
  -							break outer
  -
  -					moveElement(L, cursor2, cursor1)
  -					++cursor2
  +/datum/sortInstance/proc/mergeLo(base1, len1, base2, len2)
  +	//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
  +
  +	var/cursor1 = base1
  +	var/cursor2 = base2
  +
  +	//degenerate cases
  +	if(len2 == 1)
  +		moveElement(L, cursor2, cursor1)
  +		return
  +
  +	if(len1 == 1)
  +		moveElement(L, cursor1, cursor2+len2)
  +		return
  +
  +
  +	//Move first element of second run
  +	moveElement(L, cursor2++, cursor1++)
  +	--len2
  +
  +	outer:
  +		while(1)
  +			var/count1 = 0	//# of times in a row that first run won
  +			var/count2 = 0	//	"	"	"	"	"	"  second run won
  +
  +			//do the straightfoward thin until one run starts winning consistently
  +
  +			do
  +				//ASSERT(len1 > 1 && len2 > 0)
  +				if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
  +					moveElement(L, cursor2++, cursor1++)
  +					--len2
  +
  +					++count2
  +					count1 = 0
  +
  +					if(len2 == 0)
  +						break outer
  +				else
   					++cursor1
  -					if(--len2 == 0)
  -						break outer
  -
  -					count2 = gallopLeft(fetchElement(L,cursor1), cursor2, len2, 0)
  -					if(count2)
  -						moveRange(L, cursor2, cursor1, count2)
  -
  -						cursor2 += count2
  -						cursor1 += count2
  -						len2 -= count2
  -
  -						if(len2 == 0)
  -							break outer
  -
  -					++cursor1
  +
  +					++count1
  +					count2 = 0
  +
   					if(--len1 == 1)
   						break outer
   
  -					--minGallop
  -
  -				while((count1|count2) > MIN_GALLOP)
  -
  -				if(minGallop < 0)
  -					minGallop = 0
  -				minGallop += 2;  // Penalize for leaving gallop mode
  -
  -
  -		if(len1 == 1)
  -			//ASSERT(len2 > 0)
  -			moveElement(L, cursor1, cursor2+len2)
  -
  -		//else
  -			//ASSERT(len2 == 0)
  -			//ASSERT(len1 > 1)
  -
  -
  -	proc/mergeHi(base1, len1, base2, len2)
  -		//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
  -
  -		var/cursor1 = base1 + len1 - 1	//start at end of sublists
  -		var/cursor2 = base2 + len2 - 1
  -
  -		//degenerate cases
  -		if(len2 == 1)
  -			moveElement(L, base2, base1)
  -			return
  -
  -		if(len1 == 1)
  -			moveElement(L, base1, cursor2+1)
  -			return
  -
  -		moveElement(L, cursor1--, cursor2-- + 1)
  -		--len1
  -
  -		outer:
  -			while(1)
  -				var/count1 = 0	//# of times in a row that first run won
  -				var/count2 = 0	//	"	"	"	"	"	"  second run won
  -
  -				//do the straightfoward thing until one run starts winning consistently
  -				do
  -					//ASSERT(len1 > 0 && len2 > 1)
  -					if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
  -						moveElement(L, cursor1--, cursor2-- + 1)
  -						--len1
  -
  -						++count1
  -						count2 = 0
  -
  -						if(len1 == 0)
  -							break outer
  -					else
  -						--cursor2
  -						--len2
  -
  -						++count2
  -						count1 = 0
  -
  -						if(len2 == 1)
  -							break outer
  -				while((count1 | count2) < minGallop)
  -
  -				//one run is winning consistently so galloping may provide huge benifits
  -				//so try galloping, until such time as the run is no longer consistently winning
  -				do
  -					//ASSERT(len1 > 0 && len2 > 1)
  -
  -					count1 = len1 - gallopRight(fetchElement(L,cursor2), base1, len1, len1-1)	//should cursor1 be base1?
  -					if(count1)
  -						cursor1 -= count1
  -
  -						moveRange(L, cursor1+1, cursor2+1, count1)	//cursor1+1 == cursor2 by definition
  -
  -						cursor2 -= count1
  -						len1 -= count1
  -
  -						if(len1 == 0)
  -							break outer
  -
  -					--cursor2
  -
  -					if(--len2 == 1)
  -						break outer
  -
  -					count2 = len2 - gallopLeft(fetchElement(L,cursor1), cursor1+1, len2, len2-1)
  -					if(count2)
  -						cursor2 -= count2
  -						len2 -= count2
  -
  -						if(len2 <= 1)
  -							break outer
  -
  +			while((count1 | count2) < minGallop)
  +
  +
  +			//one run is winning consistently so galloping may provide huge benifits
  +			//so try galloping, until such time as the run is no longer consistently winning
  +			do
  +				//ASSERT(len1 > 1 && len2 > 0)
  +
  +				count1 = gallopRight(fetchElement(L,cursor2), cursor1, len1, 0)
  +				if(count1)
  +					cursor1 += count1
  +					len1 -= count1
  +
  +					if(len1 <= 1)
  +						break outer
  +
  +				moveElement(L, cursor2, cursor1)
  +				++cursor2
  +				++cursor1
  +				if(--len2 == 0)
  +					break outer
  +
  +				count2 = gallopLeft(fetchElement(L,cursor1), cursor2, len2, 0)
  +				if(count2)
  +					moveRange(L, cursor2, cursor1, count2)
  +
  +					cursor2 += count2
  +					cursor1 += count2
  +					len2 -= count2
  +
  +					if(len2 == 0)
  +						break outer
  +
  +				++cursor1
  +				if(--len1 == 1)
  +					break outer
  +
  +				--minGallop
  +
  +			while((count1|count2) > MIN_GALLOP)
  +
  +			if(minGallop < 0)
  +				minGallop = 0
  +			minGallop += 2;  // Penalize for leaving gallop mode
  +
  +
  +	if(len1 == 1)
  +		//ASSERT(len2 > 0)
  +		moveElement(L, cursor1, cursor2+len2)
  +
  +	//else
  +		//ASSERT(len2 == 0)
  +		//ASSERT(len1 > 1)
  +
  +
  +/datum/sortInstance/proc/mergeHi(base1, len1, base2, len2)
  +	//ASSERT(len1 > 0 && len2 > 0 && base1 + len1 == base2)
  +
  +	var/cursor1 = base1 + len1 - 1	//start at end of sublists
  +	var/cursor2 = base2 + len2 - 1
  +
  +	//degenerate cases
  +	if(len2 == 1)
  +		moveElement(L, base2, base1)
  +		return
  +
  +	if(len1 == 1)
  +		moveElement(L, base1, cursor2+1)
  +		return
  +
  +	moveElement(L, cursor1--, cursor2-- + 1)
  +	--len1
  +
  +	outer:
  +		while(1)
  +			var/count1 = 0	//# of times in a row that first run won
  +			var/count2 = 0	//	"	"	"	"	"	"  second run won
  +
  +			//do the straightfoward thing until one run starts winning consistently
  +			do
  +				//ASSERT(len1 > 0 && len2 > 1)
  +				if(call(cmp)(fetchElement(L,cursor2), fetchElement(L,cursor1)) < 0)
   					moveElement(L, cursor1--, cursor2-- + 1)
   					--len1
   
  +					++count1
  +					count2 = 0
  +
   					if(len1 == 0)
   						break outer
  -
  -					--minGallop
  -				while((count1|count2) > MIN_GALLOP)
  -
  -				if(minGallop < 0)
  -					minGallop = 0
  -				minGallop += 2	// Penalize for leaving gallop mode
  -
  -		if(len2 == 1)
  -			//ASSERT(len1 > 0)
  -
  -			cursor1 -= len1
  -			moveRange(L, cursor1+1, cursor2+1, len1)
  -
  -		//else
  -			//ASSERT(len1 == 0)
  -			//ASSERT(len2 > 0)
  -
  -
  -	proc/mergeSort(start, end)
  -		var/remaining = end - start
  -
  -		//If array is small, do an insertion sort
  -		if(remaining < MIN_MERGE)
  -			binarySort(start, end, start/*+initRunLen*/)
  -			return
  -
  -		var/minRun = minRunLength(remaining)
  -
  -		do
  -			var/runLen = (remaining <= minRun) ? remaining : minRun
  -
  -			binarySort(start, start+runLen, start)
  -
  -			//add data about run to queue
  -			runBases.Add(start)
  -			runLens.Add(runLen)
  -
  -			//Advance to find next run
  -			start += runLen
  -			remaining -= runLen
  -
  -		while(remaining > 0)
  -
  -		while(runBases.len >= 2)
  -			var/n = runBases.len - 1
  -			if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
  -				if(runLens[n-1] < runLens[n+1])
  -					--n
  -				mergeAt2(n)
  -			else if(runLens[n] <= runLens[n+1])
  -				mergeAt2(n)
  -			else
  -				break	//Invariant is established
  -
  -		while(runBases.len >= 2)
  -			var/n = runBases.len - 1
  -			if(n > 1 && runLens[n-1] < runLens[n+1])
  +				else
  +					--cursor2
  +					--len2
  +
  +					++count2
  +					count1 = 0
  +
  +					if(len2 == 1)
  +						break outer
  +			while((count1 | count2) < minGallop)
  +
  +			//one run is winning consistently so galloping may provide huge benifits
  +			//so try galloping, until such time as the run is no longer consistently winning
  +			do
  +				//ASSERT(len1 > 0 && len2 > 1)
  +
  +				count1 = len1 - gallopRight(fetchElement(L,cursor2), base1, len1, len1-1)	//should cursor1 be base1?
  +				if(count1)
  +					cursor1 -= count1
  +
  +					moveRange(L, cursor1+1, cursor2+1, count1)	//cursor1+1 == cursor2 by definition
  +
  +					cursor2 -= count1
  +					len1 -= count1
  +
  +					if(len1 == 0)
  +						break outer
  +
  +				--cursor2
  +
  +				if(--len2 == 1)
  +					break outer
  +
  +				count2 = len2 - gallopLeft(fetchElement(L,cursor1), cursor1+1, len2, len2-1)
  +				if(count2)
  +					cursor2 -= count2
  +					len2 -= count2
  +
  +					if(len2 <= 1)
  +						break outer
  +
  +				moveElement(L, cursor1--, cursor2-- + 1)
  +				--len1
  +
  +				if(len1 == 0)
  +					break outer
  +
  +				--minGallop
  +			while((count1|count2) > MIN_GALLOP)
  +
  +			if(minGallop < 0)
  +				minGallop = 0
  +			minGallop += 2	// Penalize for leaving gallop mode
  +
  +	if(len2 == 1)
  +		//ASSERT(len1 > 0)
  +
  +		cursor1 -= len1
  +		moveRange(L, cursor1+1, cursor2+1, len1)
  +
  +	//else
  +		//ASSERT(len1 == 0)
  +		//ASSERT(len2 > 0)
  +
  +
  +/datum/sortInstance/proc/mergeSort(start, end)
  +	var/remaining = end - start
  +
  +	//If array is small, do an insertion sort
  +	if(remaining < MIN_MERGE)
  +		binarySort(start, end, start/*+initRunLen*/)
  +		return
  +
  +	var/minRun = minRunLength(remaining)
  +
  +	do
  +		var/runLen = (remaining <= minRun) ? remaining : minRun
  +
  +		binarySort(start, start+runLen, start)
  +
  +		//add data about run to queue
  +		runBases.Add(start)
  +		runLens.Add(runLen)
  +
  +		//Advance to find next run
  +		start += runLen
  +		remaining -= runLen
  +
  +	while(remaining > 0)
  +
  +	while(runBases.len >= 2)
  +		var/n = runBases.len - 1
  +		if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
  +			if(runLens[n-1] < runLens[n+1])
   				--n
   			mergeAt2(n)
  -
  -		return L
  -
  -	proc/mergeAt2(i)
  -		var/cursor1 = runBases[i]
  -		var/cursor2 = runBases[i+1]
  -
  -		var/end1 = cursor1+runLens[i]
  -		var/end2 = cursor2+runLens[i+1]
  -
  -		var/val1 = fetchElement(L,cursor1)
  -		var/val2 = fetchElement(L,cursor2)
  -
  -		while(1)
  -			if(call(cmp)(val1,val2) <= 0)
  -				if(++cursor1 >= end1)
  -					break
  -				val1 = fetchElement(L,cursor1)
  -			else
  -				moveElement(L,cursor2,cursor1)
  -
  -				if(++cursor2 >= end2)
  -					break
  -				++end1
  -				++cursor1
  -
  -				val2 = fetchElement(L,cursor2)
  -
  -
  -		//Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run
  -		//(which isn't involved in this merge). The current run (i+1) goes away in any case.
  -		runLens[i] += runLens[i+1]
  -		runLens.Cut(i+1, i+2)
  -		runBases.Cut(i+1, i+2)
  +		else if(runLens[n] <= runLens[n+1])
  +			mergeAt2(n)
  +		else
  +			break	//Invariant is established
  +
  +	while(runBases.len >= 2)
  +		var/n = runBases.len - 1
  +		if(n > 1 && runLens[n-1] < runLens[n+1])
  +			--n
  +		mergeAt2(n)
  +
  +	return L
  +
  +/datum/sortInstance/proc/mergeAt2(i)
  +	var/cursor1 = runBases[i]
  +	var/cursor2 = runBases[i+1]
  +
  +	var/end1 = cursor1+runLens[i]
  +	var/end2 = cursor2+runLens[i+1]
  +
  +	var/val1 = fetchElement(L,cursor1)
  +	var/val2 = fetchElement(L,cursor2)
  +
  +	while(1)
  +		if(call(cmp)(val1,val2) <= 0)
  +			if(++cursor1 >= end1)
  +				break
  +			val1 = fetchElement(L,cursor1)
  +		else
  +			moveElement(L,cursor2,cursor1)
  +
  +			if(++cursor2 >= end2)
  +				break
  +			++end1
  +			++cursor1
  +
  +			val2 = fetchElement(L,cursor2)
  +
  +
  +	//Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run
  +	//(which isn't involved in this merge). The current run (i+1) goes away in any case.
  +	runLens[i] += runLens[i+1]
  +	runLens.Cut(i+1, i+2)
  +	runBases.Cut(i+1, i+2)
   
   #undef MIN_GALLOP
   #undef MIN_MERGE
  
positive.code: 
  		Returns the index at which to insert element 'key'
  	*/
  	proc/gallopLeft(key, base, len, hint)
  		//ASSERT(len > 0 && hint >= 0 && hint < len)
  
  		var/lastOffset = 0
  		var/offset = 1
  		if(call(cmp)(key, fetchElement(L,base+hint)) > 0)
  			var/maxOffset = len - hint
  			while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint+offset)) > 0)
  				lastOffset = offset
  				offset = (offset << 1) + 1
  
  			if(offset > maxOffset)
  				offset = maxOffset
  
  			lastOffset += hint
  			offset += hint
  
  		else
  			var/maxOffset = hint + 1
  			while(offset < maxOffset && call(cmp)(key, fetchElement(L,base+hint-offset)) <= 0)
  				lastOffset = offset
  				offset = (offset << 1) + 1
  
  			if(offset > maxOffset)
  				offset = maxOffset
  
  			var/temp = lastOffset
  			lastOffset = hint - offset
  			offset = hint - temp
  
  			//ASSERT(-1 <= lastOffset && lastOffset < offset && offset <= len)
  
  		//Now L[base+lastOffset] < key <= L[base+offset], so key belongs somewhere to the right of lastOffset but no farther than
  		//offset. Do a binary search with invariant L[base+lastOffset-1] < key <= L[base+offset]
  		++lastOffset
  		while(lastOffset < offset)
  			var/m = lastOffset + ((offset - lastOffset) >> 1)
  
  			if(call(cmp)(key, fetchElement(L,base+m)) > 0)
  				lastOffset = m + 1
  			else
  				offset = m
  
  		//ASSERT(lastOffset == offset)
  		return offset
  
  	/**
  	 * Like gallopLeft, except that if the range contains an element equal to
  
negative.code: 	definition of "descending" is needed so that the call can safely
  	reverse a descending sequence without violating stability.
  	*/
  /datum/sortInstance/proc/countRunAndMakeAscending(lo, hi)
  	//ASSERT(lo < hi)
  
  	var/runHi = lo + 1
  	if(runHi >= hi)
  		return 1
  
  	var/last = fetchElement(L,lo)
  	var/current = fetchElement(L,runHi++)
  
  	if(call(cmp)(current, last) < 0)
  		while(runHi < hi)
  			last = current
  			current = fetchElement(L,runHi)
  			if(call(cmp)(current, last) >= 0)
  				break
  			++runHi
  		reverseRange(L, lo, runHi)
  	else
  		while(runHi < hi)
  			last = current
  			current = fetchElement(L,runHi)
  			if(call(cmp)(current, last) < 0)
  				break
  			++runHi
  
  	return runHi - lo
  
  	//Returns the minimum acceptable run length for an array of the specified length.
  	//Natural runs shorter than this will be extended with binarySort
  /datum/sortInstance/proc/minRunLength(n)
  	//ASSERT(n >= 0)
  	var/r = 0	//becomes 1 if any bits are shifted off
  	while(n >= MIN_MERGE)
  		r |= (n & 1)
  		n >>= 1
  	return n + r
  
  	//Examines the stack of runs waiting to be merged and merges adjacent runs until the stack invariants are reestablished:
  	//	runLen[i-3] > runLen[i-2] + runLen[i-1]
  	//	runLen[i-2] > runLen[i-1]
  	//This method is called each time a new run is pushed onto the stack.
  	//So the invariants are guaranteed to hold for i<stackSize upon entry to the method
  /datum/sortInstance/proc/mergeCollapse()
  	while(runBases.len >= 2)
  		var/n = runBases.len - 1
  		if(n > 1 && runLens[n-1] <= runLens[n] + runLens[n+1])
  			if(runLens[n-1] < runLens[n+1])
  				--n
  			mergeAt(n)
  		else if(runLens[n] <= runLens[n+1])
  			mergeAt(n)
  		else
  			break	//Invariant is established
  
  
  	//Merges all runs on the stack until only one remains.
  	//Called only once, to finalise the sort
  /datum/sortInstance/proc/mergeForceCollapse()
  	while(runBases.len >= 2)
  		var/n = runBases.len - 1
  		if(n > 1 && runLens[n-1] < runLens[n+1])
  			--n
  		mergeAt(n)
  
  
  	//Merges the two consecutive runs at stack indices i and i+1
  	//Run i must be the penultimate or antepenultimate run on the stack
  	//In other words, i must be equal to stackSize-2 or stackSize-3
  /datum/sortInstance/proc/mergeAt(i)
  	//ASSERT(runBases.len >= 2)
  	//ASSERT(i >= 1)
  	//ASSERT(i == runBases.len - 1 || i == runBases.len - 2)
  
  	var/base1 = runBases[i]
  	var/base2 = runBases[i+1]
  	var/len1 = runLens[i]
  	var/len2 = runLens[i+1]
  
  	//ASSERT(len1 > 0 && len2 > 0)
  	//ASSERT(base1 + len1 == base2)
  
  	//Record the legth of the combined runs. If i is the 3rd last run now, also slide over the last run
  	//(which isn't involved in this merge). The current run (i+1) goes away in any case.
  	runLens[i] += runLens[i+1]
  	runLens.Cut(i+1, i+2)
  	runBases.Cut(i+1, i+2)
  
  
  	//Find where the first element of run2 goes in run1.
  	//Prior elements in run1 can be ignored (because they're already in place)
  	var/k = gallopRight(fetchElement(L,base2), base1, len1, 0)
  	//ASSERT(k >= 0)
  	base1 += k
  	len1 -= k
  	if(len1 == 0)
  		return
  
  	//Find where the last element of run1 goes in run2.
  	//Subsequent elements in run2 can be ignored (because they're already in place)
  	len2 = gallopLeft(fetchElement(L,base1 + len1 - 1), base2, len2, len2-1)
  	//ASSERT(len2 >= 0)
  	if(len2 == 0)
  		return
  
  	//Merge remaining runs, using tmp array with min(len1, len2) elements
  	if(len1 <= len2)
  		mergeLo(base1, len1, base2, len2)
  	else
  		mergeHi(base1, len1, base2, len2)
  
  
  	/*
  