 			if (_callbackCollection.triggerCounter == _selfTriggeredCount)
 				return;
 			
-			// reset variables and mark as busy
-			_pendingInvoke = true;
+			// reset variables
+			_invalidated = true;
 			_asyncToken = null;
 			_result = null;
 			_error = null;
-			WeaveAPI.ProgressIndicator.addTask(_groupedCallback, this);
+			
+			// we are no longer waiting for the async task
+			WeaveAPI.ProgressIndicator.removeTask(_groupedCallback);
+			
+			// stop if lazy
+			if (_lazy)
+				return;
+			
+			// stop if still busy because we don't want to invoke the task if an external dependency is not ready
+			if (WeaveAPI.SessionManager.linkableObjectIsBusy(this))
+			{
+				// make sure _groupedCallback() will not invoke the task.
+				// this is ok to do since callbacks will be triggered again when the dependencies are no longer busy.
+				_invalidated = false;
+				return;
+			}
+			
+			// mark as busy starting now because we plan to start the task inside _groupedCallback()
+			WeaveAPI.ProgressIndicator.addTask(_groupedCallback, this, _description);
 		}
 		
 		private function _groupedCallback():void
 		{
-			if (!_pendingInvoke)
-				return;
-			
-			_pendingInvoke = false;
+			if (_lazy || !_invalidated)
+				return;
+			
+			_invalidated = false;
 			
 			try
 			{
-				var invokeResult:Object = _invoke.apply(null, _invokeParams);
+				var invokeResult:Object = _task.apply(null, _taskParams);
 				_asyncToken = invokeResult as AsyncToken;
 				if (_asyncToken)
 				{

		
		public function dispose():void
		{
			_pendingInvoke = false;
			_asyncToken = null;
			_result = null;
			_error = null;

		private function _handleFault(event:FaultEvent = null, asyncToken:AsyncToken = null):void
		{
			// stop if asyncToken is no longer relevant
			if (_invalidated || _asyncToken != asyncToken)
				return;
			
			// no longer busy
