 		
 		/*************
 		 ** Testing **
-		 *************/		
-		
-		//test(); // Class('weave.utils.AsyncSort').test()
-		public static function test():void
-		{
-			for each (var n:uint in [50,3000,6000,12000,25000,50000])
+		 *************/
+		
+		//test(true); // Class('weave.utils.AsyncSort').test(false)
+		/*
+			Array.sort 50 numbers; 0.002 seconds; 487 comparisons
+			Merge Sort 50 numbers; 0.001 seconds; 208 comparisons
+			Array.sort 3000 numbers; 0.304 seconds; 87367 comparisons
+			Merge Sort 3000 numbers; 0.111 seconds; 25608 comparisons
+			Array.sort 6000 numbers; 0.809 seconds; 226130 comparisons
+			Merge Sort 6000 numbers; 0.275 seconds; 55387 comparisons
+			Array.sort 12000 numbers; 1.969 seconds; 554380 comparisons
+			Merge Sort 12000 numbers; 0.514 seconds; 119555 comparisons
+			Array.sort 25000 numbers; 9.498 seconds; 2635394 comparisons
+			Merge Sort 25000 numbers; 1.234 seconds; 274965 comparisons
+			Array.sort 50000 numbers; 37.285 seconds; 10238787 comparisons
+			Merge Sort 50000 numbers; 2.603 seconds; 585089 comparisons
+		*/
+		public static function test(useDefaultSort:Boolean):void
+		{
+			for each (var n:uint in [0,1,50,3000,6000,12000,25000,50000])
 			{
 				var array:Array = [];
 				for (var i:int = 0; i < n; i++)
-					array.push(uint(Math.random()*100));
+					array.push(Math.random() < .5 ? NaN : uint(Math.random()*100));
 				var array2:Array = array.concat();
 				
 				var start:int = getTimer();
 				_debugCompareCount = 0;
-				array.sort(_debugCompare);
+				if (useDefaultSort)
+					array.sort();
+				else
+					array.sort(_debugCompare);
 				trace('Array.sort', n, 'numbers;', (getTimer() - start) / 1000, 'seconds;',_debugCompareCount,'comparisons');
 				
+				start = getTimer();
 				_debugCompareCount = 0;
-				start = getTimer();
-				sortImmediately(array2, _debugCompare);
+				if (useDefaultSort)
+					sortImmediately(array2);
+				else
+					sortImmediately(array2, _debugCompare);
 				//trace('Merge Sort', n, 'numbers;', _immediateSorter.elapsed / 1000, 'seconds;',_debugCompareCount,'comparisons');
 				trace('Merge Sort', n, 'numbers;', (getTimer() - start) / 1000, 'seconds;',_debugCompareCount,'comparisons');
 				
-				verifySorted(array2);
-			}
-		}
-		private static function verifySorted(array:Array):void
+				if (array2.length == 1 && ObjectUtil.compare(array[0],array2[0]) != 0)
+					throw new Error("sort failed on array length 1");
+				
+				verifyNumbersSorted(array2);
+			}
+		}
+		private static function verifyNumbersSorted(array:Array):void
 		{
 			for (var i:int = 1; i < array.length; i++)
 			{
-				if (array[i - 1] > array[i])
+				if (ObjectUtil.numericCompare(array[i - 1], array[i]) > 0)
 				{
 					throw new Error("ASSERTION FAIL " + array[i - 1] + ' > ' + array[i]);
 				}

		public function beginSort(arrayToSort:*, compareFunction:Function = null):void
		{
			// initialize
			compare = compareFunction || ObjectUtil.compare;
			array = arrayToSort;
			length = array.length;
			
			// make a buffer of the same type and length
			var Type:Class = (array as Object).constructor;
			buffer = new Type();
			buffer.length = length;
			
			size = 1;
			middle = 0;
			end = 0;
			merging = false;
			elapsed = 0;
			swapped = false;
			
			if (_immediately)
			{

			
			while (getTimer() < stopTime)
			{
				if (iLeft < middle) // if there are still more items in the left sub-array
				{
					// copy smallest value to merge destination
					if (iRight < end && compare(source[iRight], source[iLeft]) < 0)
						destination[iMerged++] = source[iRight++];
					else
						destination[iMerged++] = source[iLeft++];
				}
				else if (iRight < end) // if there are still more items in the right sub-array
				{
					destination[iMerged++] = source[iRight++];
				}
				else if (end < length) // if there are still more pairs of sub-arrays to merge
				{
					// begin merging the next pair of sub-arrays
					var start:uint = end;
					middle = Math.min(start + subArraySize, length);
					end = Math.min(middle + subArraySize, length);
					iLeft = start;
					iRight = middle;
					iMerged = start;
				}
				else // done merging all pairs of sub-arrays
				{
					// use the merged destination as the next source
					var merged:* = destination;
					destination = source;
					source = merged;
					
					// start merging sub-arrays of twice the previous size
					end = 0;
					subArraySize *= 2;
					
					// stop if the sub-array includes the entire array
					if (subArraySize >= length)
						break;
				}
			}
			
			elapsed += getTimer() - time;
			
			// if one sub-array includes the entire array, we're done
			if (subArraySize >= length)
			{
				// source array is completely sorted
				if (source != original) // if source isn't the original
				{
					// copy the sorted values to the original
					for (var i:int = length - 1; i >= 0; i--)
						original[i] = source[i];
				}
				
				// clean up so the "get result()" function knows we're done
				source = null;
				destination = null;
				
				return 1; // done
			}
			
			//TODO: improve progress calculation
			return subArraySize / length; // not exactly accurate, but returns a number < 1
		}
		
		private function done():void
