 	 */
 	public class SortedIndexColumn extends DynamicColumn implements IAttributeColumn, IPrimitiveColumn
 	{
-		public function SortedIndexColumn()
-		{
-			super();
-			addImmediateCallback(this, invalidateLookup);
-		}
-
-		private function invalidateLookup():void
-		{
-			// invalidate lookup
-			_keyToIndexMap = null;
-			// TODO: set unit?
-		}
-
+		/**
+		 * This is used to store the sorted list of keys.
+		 */
+		private var _keys:Array = [];
 		/**
 		 * This object maps a key to the index of that key in the sorted list of keys.
 		 */
-		private var _keyToIndexMap:Dictionary = null;
+		private var _keyToIndexMap:Dictionary = new Dictionary(true);
+		private var _column:IAttributeColumn = null;
+		private var _triggerCount:uint = 0;
+		private var _asyncSort:AsyncSort = newLinkableChild(this, AsyncSort, handleSorted);
 		
-		/**
-		 * This is used to store the sorted list of keys.
-		 */
-		private var _keys:Array = new Array();
-
-		/**
-		 * This function returns the unique strings of the internal column.
-		 * @return The keys this column defines values for.
-		 */
-		override public function get keys():Array
-		{
-			// validate lookup table if necessary
-			if (_keyToIndexMap == null)
-				createLookupTable();
-			return _keys;
+		private function validate():void
+		{
+			_keys = super.keys.concat();
+			_column = getInternalColumn();
+			_asyncSort.beginSort(_keys, sortByNumericValue);
 		}
-
-		/**
-		 * @param key A key to test.
-		 * @return true if the key exists in this IKeySet.
-		 */
-		override public function containsKey(key:IQualifiedKey):Boolean
-		{
-			return _keyToIndexMap[key] != undefined;
-		}
-		
-		/**
-		 * This function will sort the keys and create the keyToIndexMap mapping the keys to their sorted index values.
-		 */
-		private function createLookupTable():void
-		{
-			// get the keys from the internal column
-			var keys:Array = getInternalColumn() ? getInternalColumn().keys : [];
-			// make a copy of the list of keys
-			VectorUtils.copy(keys, _keys);
-			// sort the keys based on the numeric values associated with them
-			AsyncSort.sortImmediately(_keys, sortByNumericValue);
-			// update the lookup table
-			_keyToIndexMap = new Dictionary();
-			var i:int = _keys.length;
-			while (--i > -1)
-			{
-				// since numericCompare sorts NaN at the end, ignoring NaN's won't affect the remaining indices
-				var key:IQualifiedKey = _keys[i] as IQualifiedKey;
-				if (!isNaN(getInternalColumn().getValueFromKey(key, Number)))
-					_keyToIndexMap[_keys[i]] = i;
-			}
+		private function handleSorted():void
+		{
+			_triggerCount++; // account for _asyncSort trigger
+			_keyToIndexMap = VectorUtils.createLookup(_keys);
 		}
 
 		/**

		 */
		public function deriveStringFromNumber(index:Number):String
		{
			// validate lookup table if necessary
			if (_keyToIndexMap == null)
				createLookupTable();
			// return the key at the given number as an index
			index = Math.round(index);
			// return '' if there is no key at the given index value
			if (index < 0 || index >= _keys.length)
				return '';
			return getInternalColumn() ? getInternalColumn().getValueFromKey(_keys[index], String) : '';
		}
	}
}

	import weave.api.data.IAttributeColumn;
	import weave.api.data.IPrimitiveColumn;
	import weave.api.data.IQualifiedKey;
	import weave.api.newLinkableChild;
	import weave.data.QKeyManager;
	import weave.utils.AsyncSort;
	import weave.utils.VectorUtils;
