protected void performMoveCallback(){
		//we got our move from the swingworker. 
		//Let's post our move to the UI
		if (parent == null){
			return;
		}
		if (!parent.isVisible()){
			return;
		}
		if (parent.gamestate.gameFinished){
			return; //game is over
		}
		
		AIBundle bundle = null;
		try {
			bundle = workerThread.get();
		} catch (InterruptedException e1 ){
		} 
		catch( ExecutionException e1) {
			e1.printStackTrace();
		}
		Move nextMove = bundle.getMove();
		
		if (!gamestate.allowFlying() || myTeam.getNumPieces() > 3){
			try {
				boolean mill = gamestate.movePiece(nextMove);
				GamePieceButton source = parent.pieces[nextMove.Rs][nextMove.Ps];
				GamePieceButton destination = parent.pieces[nextMove.Rd][nextMove.Pd];
				parent.pieceSelected = source; //source piece for moving against
				parent.repaint();
				destination.REPRESENTING = source.REPRESENTING;
				destination.setMode(GamePieceButton.NORMAL_MODE);
				source.setMode(GamePieceButton.HIDDEN_MODE);
				parent.updateMovedPieces();
				if (mill){
					//Make the AI find the piece to remove
					parent.repaint(); //repaint so the user sees what happens
					NineManMill.sfxplayer.playSound(WavePlayer.SOUND_MILL);
					workerThread = new AIWorkerThread(playerID, AIWorkerThread.OPERATION_DESTROY, difficulty, gamestate);
					workerThread.execute(); //run the AI destroyer in the background.
					parent.setDirections("Player "+parent.gamestate.CURRENT_TURN+" is selecting a piece to destroy...");
					//Don't finish turn. AI is not done yet. Destroy will finish the turn in it's callback
				} else {
					parent.completeTurn(); //finish turn if not a mill
				}
			}	catch (PiecePlacementException e)	{ 
				System.err.println("["+getDifficultyString()+" "+playerID+"] AI did an invalid move"); 	
			}
		} else {
			//fly mode
			GamePieceButton destination = parent.pieces[nextMove.Rd][nextMove.Pd];
			parent.pieces[nextMove.Rs][nextMove.Ps].setMode(GamePieceButton.FLY_FROM_MODE);
			parent.pieces[nextMove.Rs][nextMove.Ps].repaint(); //repaint that piece
			destination.setSourceFlyButton(parent.pieces[nextMove.Rs][nextMove.Ps]);
			//System.out.println(nextMove);
			destination.setAIFlyMove(nextMove);
			destination.setAI(this);
			destination.REPRESENTING = myTeam.getSymbol(); //this is okay as the original position will be automatically cleared.
			destination.setBlinkMode(GamePieceButton.FLY_TO_MODE);
		}
	}