 		
 		/*************
 		 ** 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]);
 				}

			
			while (getTimer() < stopTime)
			{
				if (iLeft < middle)
				{
					// copy smallest value to buffer
					if (iRight < end && compare(array[iRight], array[iLeft]) < 0)
						buffer[iBuffer++] = array[iRight++];
					else
						buffer[iBuffer++] = array[iLeft++];
				}
				else if (iRight < end)
				{
					buffer[iBuffer++] = array[iRight++];
				}
				else if (end >= length) // done merging all pairs of sub-arrays of current size
				{
					// swap sorted and unsorted arrays
					var sorted:* = buffer;
					buffer = array;
					array = sorted;
					swapped = !swapped; // keep track of whether or not this is the original array
					
					// start again from beginning of array
					size *= 2;
					end = 0;
					
					if (size >= length)
					{
						// we are done sorting.
						elapsed += getTimer() - time;
						if (swapped)
						{
							// buffer is the original, so copy the sorted values over from sorted array
							for (var i:int = length - 1; i >= 0; i--)
								buffer[i] = array[i];
							array = buffer;
						}
						buffer = null;
						return 1;
					}
				}
				else
				{
					// prepare for next merge
					start = end;
					middle = Math.min(start + size, length);
					end = Math.min(middle + size, length);
					iLeft = start;
					iRight = middle;
					iBuffer = start;
					merging = true;
				}
			}
			
			elapsed += getTimer() - time;
			
			if (length == 0)
				return 1;
			
			//TODO: improve progress calculation
			return size / length; // not exactly accurate, but returns a number < 1
		}
		
		private function done():void

		}
		
		/**
		 * This is a basic compare function similar to the default compare used by Array.sort().
		 * This function is faster than ObjectUtil.compare(), but does not do deep object compare.
		 */
		private static function defaultCompare(a:*, b:*):int
		{
			if (a === b)
				return 0;
			if (a == null)
				return 1;
			if (b == null)
				return -1;
			var typeA:String = typeof(a);
			var typeB:String = typeof(b);
			if (typeA != typeB)
				return ObjectUtil.stringCompare(typeA, typeB);
			if (typeA == 'boolean')
				return ObjectUtil.numericCompare(Number(a), Number(b));
			if (typeA == 'number')
				return ObjectUtil.numericCompare(a as Number, b as Number);
			if (typeA == 'string')
				return ObjectUtil.stringCompare(a as String, b as String);
			if (a is Date && b is Date)
				return ObjectUtil.dateCompare(a as Date, b as Date);
			return 0;
		}
		
		/**
		 * This is the sorted Array (or Vector), or null if the sort operation has not completed yet.
		 */
		public function get result():*
		{
			return source ? null : original;
		}
		
		private var original:*; // original array
		private var source:*; // contains sub-arrays currently being merged
		private var destination:*; // buffer to store merged sub-arrays
		private var compare:Function; // compares two array items
		private var length:uint; // length of original array
		private var subArraySize:uint; // size of sub-array
		private var middle:uint; // end of left and start of right sub-array
		private var end:uint; // end of right sub-array
		private var iLeft:uint; // left sub-array source index
		private var iRight:uint; // right sub-array source index
		private var iMerged:uint; // merged destination index
		private var elapsed:int; // keeps track of elapsed time inside iterate()
		private var _immediately:Boolean = false; // set in sortImmediately(), checked in beginSort()
		
		/**
		 * This will begin an asynchronous sorting operation on the specified Array (or Vector).
