 			// if the plotter is busy, stop immediately
 			if (WeaveAPI.SessionManager.linkableObjectIsBusy(_plotter))
 				return 1;
+
+			// if keys change, restart
+			if (detectLinkableObjectChange(this, _plotter, _keyFilter))
+			{
+				_iPendingRecordKey = 0;
+				_pendingRecordKeys = _plotter.keySet.keys;
+				_recordKeys = [];
+			}
 			
+			// if keys aren't ready yet, prepare keys
+			if (_pendingRecordKeys)
+			{
+				if (_iPendingRecordKey < _pendingRecordKeys.length)
+				{
+					// next key iteration - add key if included in filter
+					var key:IQualifiedKey = _pendingRecordKeys[_iPendingRecordKey] as IQualifiedKey;
+					if (_keyFilter.getInternalKeyFilter().containsKey(key))
+						_recordKeys.push(key);
+					
+					// prepare for next iteration
+					_iPendingRecordKey++;
+					
+					// not done yet
+					return 0;
+				}
+				// done with keys
+				_pendingRecordKeys = null;
+			}
+			
+			// next draw iteration
 			var progress:Number = _plotter.drawPlotAsyncIteration(this);
 			
+			// prepare for next iteration
 			_iteration++;
 			
 			return progress;

	 */
	public class PlotTask implements IPlotTask, ILinkableObject, IDisposableObject
	{
		public function PlotTask(zoomBounds:ZoomBounds, plotter:IPlotter)
		{
			_zoomBounds = zoomBounds;
			_plotter = registerLinkableChild(this, plotter);
			
			getCallbackCollection(_plotter).addImmediateCallback(this, asyncStart, true);
		}
		
		public function dispose():void

		
		private var _bitmap:Bitmap = new Bitmap();
		private var _plotter:IPlotter = null;
		private var _keyFilter:IDynamicKeyFilter = null;
		private var _zoomBounds:ZoomBounds;
		private var _tempDataBounds:Bounds2D = new Bounds2D();
		private var _tempScreenBounds:Bounds2D = new Bounds2D();
		private var _iteration:uint = 0;
		private var _recordKeys:Array;
		private var _asyncState:Object;
		private var _pendingRecordKeys:Array;
		private var _iPendingRecordKey:uint;
		
		/*
		
		todo:
		add a way to disable the task
		
		*/
		
